Szukaj…


Parametry

Kwantyfikatory Opis
? Dopasuj poprzedni znak lub podwyrażenie 0 lub 1 razy (najlepiej 1).
* Dopasuj poprzedni znak lub podwyrażenie 0 lub więcej razy (jak najwięcej).
+ Dopasuj poprzedni znak lub podwyrażenie 1 lub więcej razy (jak najwięcej).
{n} Dopasuj poprzedni znak lub podwyrażenie dokładnie n razy.
{min,} Dopasuj poprzedni znak lub podwyrażenie min lub więcej razy (tyle, ile to możliwe).
{0,max} Dopasuj poprzedni znak lub podwyrażenie maksymalnie lub mniej razy (jak najbliżej maksimum, jak to możliwe).
{min,max} Dopasuj poprzedni znak lub podwyrażenie co najmniej min razy, ale nie więcej niż maksimum razy (jak najbliżej maksimum, jak to możliwe).
Leniwe kwantyfikatory Opis
?? Dopasuj poprzedni znak lub podwyrażenie 0 lub 1 razy (najlepiej 0).
*? Dopasuj poprzedni znak lub podwyrażenie 0 lub więcej razy (możliwie jak najmniej).
+? Dopasuj poprzedni znak lub podwyrażenie 1 lub więcej razy (tak mało, jak to możliwe).
{n}? Dopasuj poprzedni znak lub podwyrażenie dokładnie n razy. Bez różnicy między wersją chciwą a leniwą.
{min,}? Dopasuj poprzedni znak lub podwyrażenie min lub więcej razy (jak najbliżej min, jak to możliwe).
{0,max}? Dopasuj poprzedni znak lub podwyrażenie maksymalnie lub mniej razy (możliwie jak najmniej).
{min,max}? Dopasuj poprzedni znak lub podwyrażenie co najmniej min razy, ale nie więcej niż maksimum razy (możliwie jak najbliżej min ).

Uwagi

Łakomstwo

Chciwy kwantyfikator zawsze próbuje powtórzyć pod-wzór tyle razy, ile to możliwe, przed zbadaniem krótszych dopasowań poprzez cofanie.

Zasadniczo chciwy wzór będzie pasował do jak najdłuższego ciągu.

Domyślnie wszystkie kwantyfikatory są zachłanne.

Lenistwo

Leniwy (zwany także niechcianym lub niechętnym ) kwantyfikator zawsze próbuje powtórzyć pod-wzór tak mało razy, jak to możliwe, przed badaniem dłuższych dopasowań przez rozwinięcie.

Ogólnie rzecz biorąc, leniwy wzór będzie pasował do możliwie najkrótszego ciągu.

Aby sprawić, by kwantyfikatory były leniwe, po prostu dodaj ? do istniejącego kwantyfikatora, np. +? , {0,5}? .

Pojęcie chciwości i lenistwa istnieje tylko w silnikach wycofujących

Pojęcie chciwego / leniwego kwantyfikatora istnieje tylko w silnikach wyrażeń zwrotnych. W silnikach wyrażeń regularnych bez śledzenia lub silnikach wyrażeń zgodnych z POSIX kwantyfikatory określają tylko górną i dolną granicę powtórzenia, bez określania, jak znaleźć dopasowanie - te silniki zawsze będą pasować do najdłuższego łańcucha po lewej stronie, niezależnie od tego.

Chciwość kontra lenistwo

Biorąc pod uwagę następujące dane wejściowe:

aaaaaAlazyZgreeedyAlaaazyZaaaaa

Użyjemy dwóch wzorów: jeden chciwy: A.*Z , a drugi leniwy: A.*?Z Te wzorce dają następujące dopasowania:

  • A.*Z daje 1 dopasowanie: AlazyZgreeedyAlaaazyZ (przykłady: Regex101 , Rubular )
  • A.*?Z daje 2 dopasowania: AlazyZ i AlaaazyZ (przykłady: Regex101 , Rubular )

Najpierw skup się na tym, co robi A.*Z Gdy pasuje do pierwszego A ,. .* , Będąc zachłannym, próbuje dopasować tyle samo . jak to możliwe.

aaaaaAlazyZgreeedyAlaaazyZaaaaa
     \________________________/
      A.* matched, Z can't match

Ponieważ Z nie pasuje, cewki silnika i .* Muszą następnie pasować o jeden mniej . :

aaaaaAlazyZgreeedyAlaaazyZaaaaa
     \_______________________/
      A.* matched, Z can't match

Dzieje się to jeszcze kilka razy, aż w końcu do tego dojdzie:

aaaaaAlazyZgreeedyAlaaazyZaaaaa
     \__________________/
      A.* matched, Z can now match

Teraz Z może się zgadzać, więc ogólny wzór pasuje:

aaaaaAlazyZgreeedyAlaaazyZaaaaa
     \___________________/
      A.*Z matched

Natomiast niechętne (leniwe) powtarzanie w A.*?Z najpierw pasuje do kilku . jak to możliwe, a następnie biorąc więcej . jako niezbędne. To wyjaśnia, dlaczego znajduje dwa dopasowania w danych wejściowych.

Oto wizualna reprezentacja dopasowania dwóch wzorów:

aaaaaAlazyZgreeedyAlaaazyZaaaaa
     \____/l      \______/l      l = lazy
     \_________g_________/       g = greedy

Przykład oparty na odpowiedzi udzielonej przez wieloskładnikowe środki smarujące .

Standard POSIX nie obejmuje ? operator, tak wiele silników wyrażeń regularnych POSIX nie ma leniwego dopasowania. Podczas gdy refaktoryzacja, szczególnie w przypadku „największej sztuczki w historii” , może w niektórych przypadkach pomóc w dopasowaniu, jedynym sposobem na prawdziwe leniwe dopasowanie jest użycie silnika, który ją obsługuje.

Granice z wieloma dopasowaniami

Jeśli masz dane wejściowe z dobrze zdefiniowanymi granicami i oczekujesz więcej niż jednego dopasowania w ciągu, masz dwie opcje:

  • Korzystanie z leniwych kwantyfikatorów;
  • Używanie zanegowanej klasy postaci.

Rozważ następujące:

Masz prosty silnik szablonów, chcesz zastąpić podciągi takie jak $[foo] gdzie foo może być dowolnym ciągiem. Chcesz zamienić ten podciąg na cokolwiek opartego na części między [] .

Możesz spróbować czegoś takiego jak \$\[(.*)\] , A następnie użyć pierwszej grupy przechwytywania.

Problem polega na tym, że jeśli masz ciąg taki jak something $[foo] lalala $[bar] something else będzie pasować

something $[foo] lalala $[bar] something else
          | \______CG1______/|
          \_______Match______/

Grupa przechwytująca to foo] lalala $[bar która może, ale nie musi być poprawna.

Masz dwa rozwiązania

  1. Używanie lenistwa: w tym przypadku * leniwość jest jednym ze sposobów na znalezienie właściwych rzeczy. Więc zmieniasz wyrażenie na \$\[(.*?)\]

  2. Używając zanegowanej klasy znaków: [^\]] zmieniasz wyrażenie na \$\[([^\]]*)\] .

W obu rozwiązaniach wynik będzie taki sam:

something $[foo] lalala $[bar] something else
          | \_/|        | \_/|
          \____/        \____/

Grupa przechwytywania to odpowiednio foo i bar .


Używanie zanegowanej klasy znaków zmniejsza problem cofania się i może zaoszczędzić dużo czasu procesorowi, jeśli chodzi o duże nakłady.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow