Regex plus vs różnica gwiazd?

90

Jaka jest różnica pomiędzy:

(.+?)

i

(.*?)

kiedy używam go w moim preg_matchwyrażeniu regularnym php ?

David19801
źródło

Odpowiedzi:

150

Nazywa się je kwantyfikatorami.

* 0 lub więcej poprzedniego wyrażenia

+ 1 lub więcej poprzedniego wyrażenia

Domyślnie kwantyfikator jest chciwy, co oznacza, że ​​dopasowuje jak najwięcej znaków.

Gdy ?kwantyfikator zmieni zachowanie, aby ten kwantyfikator był „niesmaczny”, oznacza, że ​​będzie pasował tak mało, jak to możliwe.

Przykład chciwy / nieszczęśliwy

Na przykład w ciągu „ abab

a.*b dopasuje „abab” (preg_match_all zwróci jedno dopasowanie, „abab”)

while a.*?bdopasuje tylko początkowe „ab” (preg_match_all zwróci dwa dopasowania, „ab”)

Możesz przetestować swoje wyrażenia regularne online, np. Na Regexr, zobacz chciwy przykład tutaj

stema
źródło
2
„leniwy” jest bardziej powszechne określenie „ungreedy”
Walter Tross
Przykład jest nieprawidłowy. Zarówno (.+?)i (.*?)zachowują się inaczej w różnych pozycji wyrażeń regularnych, które są a(.+?), (.+?)b, a(.+?)b, a(.*?), (.*?)b, a(.*?)b.
Louis55
Dlaczego a. * B nie zwróciłby „ab”? Czy nie mówi „słowo, które ma od a do b, 0 lub więcej znaków”, dlatego ab ma zero znaków między i może być dopasowaniem. Dlaczego jest to niepoprawne?
Hello World
@HelloWorld, ma to związek z chciwością, którą wyjaśniłem powyżej. .*będzie pasować tak bardzo, jak to możliwe. Jeśli chcesz zatrzymać się tak wcześnie, jak to możliwe, musisz zrobić to nieszczęśliwie.*?
stema
22

Pierwsza ( +) to co najmniej jeden znak . Druga ( *) zawiera zero lub więcej znaków . Obie nie są chciwe ( ?) i pasują do wszystkiego ( .).

Quentin
źródło
1
To zależy od tego, czy modyfikator s jest ustawiony, czy nie.
Quentin
8

A +pasuje do co najmniej jednego wystąpienia poprzedniego wzorca. A *dopasowuje zero lub więcej wystąpień poprzedniego wzorca.

Zasadniczo, jeśli używasz a +, musi istnieć co najmniej jedno wystąpienie wzorca, jeśli *go użyjesz , nadal będzie pasować, jeśli nie ma jego instancji.

DaveRandom
źródło
8

+ dopasowuje co najmniej jeden znak

* dopasowuje dowolną liczbę (w tym 0) znaków

Znak ?wskazuje na leniwe wyrażenie, więc dopasuje jak najmniej znaków.

Xophmeister
źródło
8

Rozważ poniżej, jaki ciąg ma pasować.

ab

Wzorzec (ab.*)zwróci dopasowanie dla grupy przechwytywania z wynikiemab

Podczas gdy wzór (ab.+)nie będzie pasował i nic nie zwróci.

Ale jeśli zmienisz ciąg na następujący, powróci on abado wzorca(ab.+)

aba
Azri Jamil
źródło
Myślę, że jest to lepsza odpowiedź konkretnie na pytanie + vs *
Terrence
6

+jest jedynką minimalną, *może też wynosić zero.

jeroen
źródło
"+ is minimal one"co to zdanie oznacza?
Det
5

W wyrażeniu regularnym {i,f}oznacza „między ido fdopasowań”. Spójrzmy na następujące przykłady:

  • {3,7} oznacza od 3 do 7 meczów
  • {,10} oznacza do 10 trafień bez dolnego limitu (czyli dolny limit to 0)
  • {3,} oznacza co najmniej 3 dopasowania bez górnej granicy (tj. górną granicą jest nieskończoność)
  • {,} oznacza brak górnej lub dolnej granicy dla liczby dopasowań (tj. dolna granica to 0, a górna to nieskończoność)
  • {5} oznacza dokładnie 4

Większość dobrych języków zawiera skróty, podobnie jak RegEx:

  • + to skrót od {1,}
  • * to skrót od {,}
  • ? to skrót od {,1}

Oznacza to, że +wymaga co najmniej 1 dopasowania, *akceptuje dowolną liczbę dopasowań lub nie ?akceptuje żadnych dopasowań i akceptuje nie więcej niż 1 dopasowanie lub zero dopasowań.

Kredyt: Codecademy.com

Miladiouss
źródło
4

Gwiazdka jest bardzo podobna do plusa, jedyną różnicą jest to, że podczas gdy plus pasuje do 1 lub więcej poprzedzających znaków / grup, gwiazda odpowiada 0 lub więcej.

Duch Madary
źródło
2

Myślę, że poprzednie odpowiedzi nie wskazują na prosty przykład:

na przykład mamy tablicę:

numbers = [5, 15]

Następujące wyrażenie regularne ^[0-9]+pasuje: 15tylko. Jednak ^[0-9]*pasuje do obu 5 and 15. Różnica polega na tym, że +operator wymaga co najmniej jednego duplikatu poprzedniego wyrażenia regularnego

Crt
źródło