Szukałem znaczenia tych wyrażeń, ale nie mogłem zrozumieć dokładnej różnicy między nimi. Oto, co mówią:
?:
Dopasuj wyrażenie, ale go nie przechwytuj.?=
Dopasuj przyrostek, ale wyklucz go z przechwytywania.?!
Dopasuj, jeśli brak sufiksu.
Próbowałem używać ich w prostym wyrażeniu regularnym i otrzymałem podobne wyniki dla wszystkich. przykład: poniższe 3 wyrażenia dają bardzo podobne wyniki.
[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?!\.[a-zA-Z0-9]+)*
[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?=\.[a-zA-Z0-9]+)*
[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9]+)*
javascript
regex
RK Poddar
źródło
źródło
*
po grupach, więc są po prostu ignorowane.Odpowiedzi:
Różnica między
?=
i?!
polega na tym, że to pierwsze wymaga dopasowania danego wyrażenia, a drugie wymaga, aby nie pasowało. Na przykłada(?=b)
dopasuje „a” do „ab”, ale nie „a” w „ac”. Natomiasta(?!b)
dopasuje „a” do „ac”, ale nie „a” in „ab”.Różnica między
?:
i?=
polega na tym, że?=
wyklucza wyrażenie z całego dopasowania, a?:
po prostu nie tworzy grupy przechwytywania. Na przykłada(?:b)
dopasuje „ab” do „abc”, aa(?=b)
dopasuje tylko „a” do „abc”.a(b)
dopasuje „ab” w „abc” i utworzy przechwycenie zawierające „b”.źródło
Proszę sprawdzić tutaj: http://www.regular-expressions.info/lookaround.html, aby zapoznać się z bardzo dobrym samouczkiem i przykładami dotyczącymi lookahead w wyrażeniach regularnych.
źródło
Aby lepiej zrozumieć, zastosujmy trzy wyrażenia oraz grupę przechwytywania i przeanalizujmy każde zachowanie.
()
grupa przechwytująca - wyrażenie regularne wewnątrz nawiasów musi być dopasowane, a dopasowanie tworzy grupę przechwytującą(?:)
grupa nie przechwytująca - wyrażenie regularne wewnątrz nawiasów musi być dopasowane, ale nie tworzy grupy przechwytującej(?=)
pozytywne spojrzenie w przyszłość - zapewnia, że wyrażenie regularne musi zostać dopasowane(?!)
negatywne spojrzenie w przyszłość - zapewnia, że dopasowanie wyrażenia regularnego nie jest możliweZłóżmy wniosek
q(u)i
o rzucenie palenia .q
pasuje q, a grupa przechwytującau
pasuje do u . Mecz wewnątrz grupy przechwytujących zostaje podjęty i zostaje utworzona grupa przechwytująca. Więc silnik kontynuujei
. Ii
będzie pasować do i . Ta ostatnia próba dopasowania zakończyła się sukcesem. qui zostanie dopasowany i zostanie utworzona grupa przechwytywania z u .Złóżmy wniosek
q(?:u)i
o rzucenie palenia . Ponownie,q
dopasowuje q, a grupa bez przechwytywaniau
pasuje do u . Dopasowanie z grupy bez przechwytywania jest brane, ale grupa przechwytująca nie jest tworzona. Więc silnik kontynuujei
. Ii
będzie pasować do i . Ta ostatnia próba dopasowania zakończyła się sukcesem. qui jest dopasowaneZłóżmy wniosek
q(?=u)i
o rzucenie palenia . Lookahead jest dodatni i następuje po nim kolejny token. Ponownieq
dopasowuje q iu
dopasowuje u . Ponownie, dopasowanie z lookahead musi zostać odrzucone, więc silnik cofa się zi
ciągu do u . Lookahead powiodło się, więc silnik działa daleji
. Alei
nie można dopasować do ciebie . Więc ta próba dopasowania kończy się niepowodzeniem.Złóżmy wniosek
q(?=u)u
o rzucenie palenia . Lookahead jest dodatni i następuje po nim kolejny token. Ponownieq
dopasowuje q iu
dopasowuje u . Dopasowanie z wyprzedzenia musi zostać odrzucone, więc silnik cofa się zu
ciągu do u . Lookahead powiodło się, więc silnik działa daleju
. Iu
pasuje do ciebie . Więc ta próba dopasowania zakończyła się sukcesem. qu jest dopasowanyZłóżmy wniosek
q(?!i)u
o rzucenie palenia . Nawet w tym przypadku lookahead jest dodatni (ponieważi
nie pasuje) i następuje po nim inny token. Ponownieq
pasuje do q, ai
nie do u . Dopasowanie z wyprzedzenia musi zostać odrzucone, więc silnik cofa się zu
ciągu do u . Lookahead powiodło się, więc silnik działa daleju
. Iu
pasuje do ciebie . Więc ta próba dopasowania zakończyła się sukcesem. qu jest dopasowanyPodsumowując, prawdziwa różnica między grupami z wyprzedzeniem i bez przechwytywania polega na tym, czy chcesz po prostu przetestować istnienie lub przetestować i zapisać dopasowanie. Przechwytywanie grupy jest drogie, więc używaj jej rozsądnie.
źródło
Spróbuj dopasować
foobar
do tych:Pierwsze wyrażenie regularne będzie pasowało i zwróci „bar” jako pierwsze przesłanie -
(?=b)
dopasowuje „b”, ale go nie zużywa, pozostawiając je dla następujących nawiasów.Drugie wyrażenie regularne NIE będzie pasować, ponieważ oczekuje, że po „foo” nastąpi coś innego niż „b”.
(?:...)
ma dokładnie taki sam efekt jak simple(...)
, ale nie zwraca tej części jako przesłania.źródło
Najprostszym sposobem zrozumienia asercji jest traktowanie ich jako polecenia wstawionego do wyrażenia regularnego. Gdy silnik przejdzie do asercji, natychmiast sprawdzi stan opisany w asercji. Jeśli wynik jest prawdziwy, kontynuuj wykonywanie wyrażenia regularnego.
źródło
To jest prawdziwa różnica:
Jeśli nie obchodzi Cię zawartość po „?:” Lub „? =”, „?:” I „? =” Są takie same. Oba są w porządku.
Ale jeśli potrzebujesz tych treści do dalszego przetwarzania (nie tylko dopasowywania całości. W takim przypadku możesz po prostu użyć "a (b)") Zamiast tego musisz użyć "? =". Ponieważ „?:” Po prostu przez to zniknie.
źródło