Autorytatywnym odniesieniem do pragmatycznych kwestii związanych z wdrażaniem silników regex jest seria trzech postów na blogu Russa Coxa . Jak opisano tam, ponieważ odwołania wsteczne powodują, że Twój język jest nieregularny, są one implementowane przy użyciu śledzenia wstecznego .
Spojrzenia na przyszłość i spojrzenia, podobnie jak wiele funkcji silników dopasowywania wyrażeń regularnych, nie pasują do paradygmatu decydowania, czy łańcuch znaków należy do języka, czy nie. Zamiast wyrażeń regularnych zwykle szukamy podciągów w większym ciągu. „Dopasowanie” to podciągi będące elementami języka, a zwracana wartość to początek i koniec podłańcucha w obrębie większego łańcucha.
Istota lookaheads i lookbehinds to nie tyle wprowadzenie umiejętności dopasowania nietypowych języków, co raczej dostosowanie miejsca, w którym silnik zgłasza początkowe i końcowe punkty dopasowanego podłańcucha.
Opieram się na opisie pod adresem http://www.regular-expressions.info/lookaround.html . Silniki wyrażeń regularnych, które obsługują tę funkcję (Perl, TCL, Python, Ruby, ...) wydają się być oparte na cofaniu (tj. Obsługują znacznie większy zestaw języków niż tylko zwykłe języki). Wydaje się, że wdrażają tę funkcję jako stosunkowo „proste” rozszerzenie cofania, zamiast próbować zbudować prawdziwe skończone automaty do wykonania zadania.
Pozytywne spojrzenie w przyszłość
Składnia pozytywnego oczekiwania jest (?=
wyrażeniem regularnym)
. Na przykład q(?=u)
dopasowuje q
tylko, jeśli następuje po nim u
, ale nie pasuje do u
. Wyobrażam sobie, że wprowadzają to z pewną odmianą cofania. Utwórz FSM dla wyrażenia przed pozytywnym wyprzedzeniem. Kiedy to się zapamięta, pamiętaj, gdzie się skończyło i uruchom nowy FSM, który reprezentuje wyrażenie wewnątrz pozytywnego spojrzenia w przyszłość. Jeśli to pasuje, to masz „dopasowanie”, ale dopasowanie „kończy się” tuż przed pozycją, w której rozpoczęło się pozytywne spojrzenie z wyprzedzeniem.
Jedyną częścią tego, która byłaby trudna bez cofania, jest to, że musisz pamiętać punkt na wejściu, w którym rozpoczyna się przeglądarka, i przenieść taśmę wejściową z powrotem do tej pozycji po zakończeniu dopasowania.
Negatywne spojrzenie w przyszłość
Składnia negatywnego wyglądu jest (?!
wyrażeniem regularnym)
. Na przykład q(?!u)
dopasowuje q
tylko wtedy, gdy nie następuje po nim u
. Może to być albo q
następująca po nim inna postać, albo a q
na samym końcu łańcucha. Wyobrażam sobie, że jest to realizowane przez utworzenie NFA dla wyrażenia wyprzedzającego, a następnie odniesie sukces tylko wtedy, gdy NFA nie dopasuje kolejnego ciągu.
Jeśli chcesz to zrobić bez polegania na cofaniu, możesz zignorować NFA wyrażenia lookahead, a następnie potraktuj to tak samo, jak pozytywny lookahead.
Pozytywny wygląd
(?<=
)
(?=q)u
u
q
q
nnn
Możesz być w stanie to zaimplementować bez cofania się, biorąc przecięcie „łańcucha zakończonego wyrażeniem regularnym ” z dowolną częścią wyrażenia regularnego występującego przed operatorem lookbehind. Będzie to trudne, ponieważ wyrażenie regularne może wymagać spojrzenia wstecz niż obecny początek danych wejściowych.
Negatywne spojrzenie
Składnia negatywnego wyglądu jest (?<!
wyrażeniem regularnym)
. Na przykład (?<!q)u
pasuje u
, ale tylko wtedy, gdy nie jest poprzedzone znakiem q
. Więc byłoby dopasować u
się umbrella
i u
na doubt
, ale nie u
w quick
. Znowu wydaje się, że dzieje się to poprzez obliczenie długości wyrażenia regularnego , utworzenie kopii zapasowej tylu znaków, testowanie dopasowania z wyrażeniem regularnym , ale teraz niepowodzenie całego dopasowania, jeśli wygląd jest zgodny.
Możesz być w stanie to zaimplementować bez cofania się, biorąc negację wyrażenia regularnego, a następnie robiąc to samo, co zrobiłbyś dla pozytywnego wyglądu.