Wyrażenie regularne: najmniejsze możliwe dopasowanie lub dopasowanie niereklamowane

98

Jak powiedzieć wyrażeniu RegEx (wersja .NET), aby uzyskać najmniejsze prawidłowe dopasowanie zamiast największego?

Jonathan Allen
źródło

Odpowiedzi:

192

W przypadku wyrażenia regularnego, takiego jak .*lub .+, dołącz znak zapytania ( .*?lub .+?), aby dopasować jak najmniej znaków. Aby opcjonalnie dopasować sekcję, (?:blah)?ale bez dopasowywania, chyba że jest to absolutnie konieczne, użyj czegoś takiego jak (?:blah){0,1}?. W przypadku powtarzającego się dopasowania (przy użyciu {n,}lub {n,m}składni) dołącz znak zapytania, aby dopasować jak najmniejszą liczbę (np. {3,}?Lub {5,7}?).

Pomocna może być również dokumentacja dotycząca kwantyfikatorów wyrażeń regularnych .

DMI
źródło
7
Nie wiem, czy tylko ja mam to nieporozumienie, ale ważne jest, aby pamiętać: chociaż prawdą jest, że niechciwy operator dopasuje jak najmniej znaków, nadal może nie być to dopasowanie, którego szuka dla. „Jak najmniej znaków” nie oznacza „najkrótszego możliwego dopasowania” w odniesieniu do standardów RegEx. Zobacz odpowiedź poniżej mojego komentarza: With abcabkand a.+?k, RegEx dopasuje cały ciąg.
finefoot
Linia2 "ale bez dopasowania, chyba że jest to absolutnie konieczne": Co to oznacza?
Deszcz
70

Operator nie chciwy ?. Tak jak to:

.*?
David Hedlund
źródło
45

Operator niechciwy nie oznacza najkrótszego możliwego dopasowania:

abcabk

a.+?k dopasuje cały ciąg (w tym przykładzie) zamiast tylko trzech ostatnich znaków.

Zamiast tego chciałbym znaleźć najmniejsze możliwe dopasowanie.

To jest ostatnie możliwe dopasowanie dla „ a”, aby nadal zezwalać na wszystkie dopasowania k.

Myślę, że jedynym sposobem na to jest użycie wyrażenia takiego jak:

a[^a]+?k

Jonathan
źródło
2
Lub szukaj w odwrotnej kolejności, zaczynając od końca, gdy dopasowania są zagnieżdżone: „(ab (abk) bk)”.
LBogaardt
7
@LBogaardt jak można wyszukiwać w odwrotnej kolejności? nie rozumiem
Azerafati
2
@LBogaardt Wciąż otwarte pytanie: Jak można wyszukiwać w odwrotnej kolejności? Powiedzmy, że chcę dostać cab. Jeśli moje dane wejściowe to caaacabi wyszukam a.*?bje, zwróci pełny ciąg zamiast krótkiego dopasowania wewnątrz. Jak szukać wstecz od b?
C4d
3
Odwróć ciąg, a następnie zastosuj wyrażenie regularne.
Jonathan Allen
3
To jest bardzo pomocne. Dla ludzi takich jak ja próbujących zrozumieć, co się tutaj dzieje, jest generyczna forma START[^START]*?END(gdzie START i END to początkowe i końcowe wyrażenia regularne znaków). Zasadniczo oznacza to „dopasuj wszystko od START do END, gdzie postacie pośrednie nie obejmują START ponownie”
derekantrican,