Wpis z mikrobloga

#programowanie #regexp próbuję zdebuggować moją ekspresję którą konstruuję ( #cpp #qt ) w ten sposób:

"\{ARGS" + QString("(?:[(\d+),(\w+)?\])?").repeated(64) + "\}"
czyli odpowiadającą np. napisowi takiemu jak ten:

{ARGS[2,1][10,D][2,255][10,wykop]}

z tym, że ciąg wyrazów może być dłuższy (maksymalnie 64 pary). Działało dobrze póki miałem 16 par, a teraz przy 64 dostaję brak zgodności i na http://regex101.com dostaję "catastrophic backtracking" opisane tutaj: https://www.regular-expressions.info/catastrophic.html - nie umiem jednak zrozumieć jak przerobić moją ekspresję... problem polega na tym, że nie wiem ile będzie argumentów w stringu. Wcześniejszy regex to po prostu "+" zamiast "repeated" ale wtedy nie mogłem pobierać argumentów z grup... myślę czy nie prościej zmienić podejście i bezpośrednio iterować sobie po stringu? będzie wolniej, szybciej?
  • 6
  • Odpowiedz
  • Otrzymuj powiadomienia
    o nowych komentarzach

@keton22: najpierw masz "{ARGS",
całość kończy się '}',
po środku masz jedną lub więcej parę cyfra-przecinek-słowo (najczęściej cyfra-przecinek-cyfra, pierwsza cyfra to rodzaj argumentu i "2" znaczy, że po przecinku będzie cyfra, a "10", że słowo bez spacji).

Format można opisać tak: \{ARGS(?:[(\d+),(\w+)?\])+\} ale wtedy nie mogę iterować po argumentach więc ktoś mi poradził, że jeżeli to rozbiję i zamiast środkowej grupy dam (?:[(\d+),(\w+)?\])? tyle razy ile wynosi maksymalna ilość argumentów
  • Odpowiedz
@s_theCapt: poszedłbym w coś takiego (?>[([0-9]+)\,([0-9,a-z,A-Z]+)\]) i dał do tego if(x.startsWith("{ARGS") && x.endsWith("}")). W ten sposób łapie to o co chodzi i jest eszcze szybkie. Możnaby sprawdzać w 1 regexpie ale masz dodatkowe grupy i wydajność szlag trafi.
EDIT zobacz sobie w regex101, różnica jest subtelna ale powinieneś być w stanie iterować w przeciwieństwie do twojego regexa.
  • Odpowiedz