Regular Expressions
Referencje
Szukaj…
Podstawy
Odwołania wsteczne służą do dopasowania tego samego tekstu, do którego wcześniej pasowała grupa przechwytująca. Pomaga to zarówno w ponownym użyciu poprzednich części wzoru, jak i w zapewnieniu dopasowania dwóch kawałków łańcucha.
Na przykład, jeśli próbujesz sprawdzić, czy łańcuch ma cyfrę od zera do dziewięciu, separator, taki jak łączniki, ukośniki, a nawet spacje, małą literę, inny separator, a następnie kolejną cyfrę od zera do dziewięciu, możesz użyj wyrażenia regularnego w ten sposób:
[0-9][-/ ][a-z][-/ ][0-9]
To pasowałoby do 1-a-4
, ale pasowałoby również do 1-a/4
lub 1 a-4
. Jeśli chcemy, aby separatory były zgodne, możemy użyć grupy przechwytywania i referencji wstecznej. Odwołanie wsteczne obejrzy dopasowanie znalezione we wskazanej grupie przechwytywania i upewni się, że lokalizacja odniesienia wstecznego dokładnie pasuje.
Korzystając z tego samego przykładu, wyrażenie regularne wyglądałoby następująco:
[0-9]([-/ ])[a-z]\1[0-9]
\1
oznacza pierwszą grupę przechwytywania we wzorcu. Przy tej małej zmianie regex pasuje teraz do 1-a-4
lub 1 a 4
ale nie do 1 a-4
lub 1-a/4
.
Liczba, która ma być użyta jako odniesienie, zależy od lokalizacji grupy przechwytywania. Liczba może wynosić od jednego do dziewięciu i można ją znaleźć, licząc grupy przechwytywania.
([0-9])([-/ ])[a-z][-/ ]([0-9])
|--1--||--2--| |--3--|
Zagnieżdżone grupy przechwytywania nieznacznie zmieniają tę liczbę. Najpierw policz zewnętrzną grupę przechwytywania, a następnie następny poziom i kontynuuj, aż opuścisz gniazdo:
(([0-9])([-/ ]))([a-z])
|--2--||--3--|
|-------1------||--4--|
Niejednoznaczne odniesienia wsteczne
Problem: Musisz dopasować tekst określonego formatu, na przykład:
1-a-0
6/p/0
4 g 0
To cyfra, separator (jeden z -
, /
lub spacja), litera, ten sam separator i zero.
Naiwne rozwiązanie: dostosowując wyrażenie regularne z przykładu Podstawy , wymyślisz ten wyrażenie regularne:
[0-9]([-/ ])[a-z]\10
Ale to prawdopodobnie nie zadziała. Większość smaków wyrażeń regularnych obsługuje więcej niż dziewięć grup przechwytywania, a bardzo niewiele z nich jest wystarczająco inteligentnych, aby zdać sobie sprawę, że ponieważ istnieje tylko jedna grupa przechwytywania, \10
musi być odniesieniem wstecz do grupy 1, a następnie dosłownie 0
. Większość smaków potraktuje to jako odniesienie do grupy 10. Kilka z nich zgłosi wyjątek, ponieważ nie ma grupy 10; reszta po prostu nie będzie pasować.
Istnieje kilka sposobów uniknięcia tego problemu. Jednym z nich jest użycie nazwanych grup (i nazwanych odwołań wstecznych):
[0-9](?<sep>[-/ ])[a-z]\k<sep>0
Jeśli Twój język wyrażeń regularnych obsługuje ten format, format \g{n}
(gdzie n
jest liczbą) może zawrzeć liczbę odsyłacza w nawiasach klamrowych, aby oddzielić ją od kolejnych cyfr:
[0-9]([-/ ])[a-z]\g{1}0
Innym sposobem jest użycie rozszerzonego formatowania wyrażeń regularnych, oddzielając elementy nieznacznymi białymi spacjami (w Javie musisz uciec od spacji w nawiasach):
(?x) [0-9] ([-/ ]) [a-z] \1 0
Jeśli Twój smak wyrażenia regularnego nie obsługuje tych funkcji, możesz dodać niepotrzebną, ale nieszkodliwą składnię, na przykład grupę nie przechwytującą:
[0-9]([-/ ])[a-z](?:\1)0
... lub sztuczny kwantyfikator (jest to prawdopodobnie jedyna okoliczność, w której przydatne jest {1}
):
[0-9]([-/ ])[a-z]\1{1}0