Przechwytywanie i grupowanie
Grupa przechwytywania (pattern)
tworzy grupę, która ma właściwość przechwytywania .
Powiązany, który często można zobaczyć (i używać), to (?:pattern)
, który tworzy grupę bez właściwości przechwytywania , stąd nazywana grupą nieprzechwytywaną .
Grupa jest zwykle używana, gdy trzeba powtórzyć sekwencję wzorców, np. (\.\w+)+
Lub określić, gdzie zmiana powinna obowiązywać, np. ^(0*1|1*0)$
( ^
, Then 0*1
lub 1*0
, then $
) versus ^0*1|1*0$
( ^0*1
lub 1*0$
).
Grupa przechwytywania, oprócz grupowania, nagra również tekst dopasowany do wzorca wewnątrz grupy przechwytywania (pattern)
. Korzystanie z przykładem, (.*):
, .*
tenis ABC
i :
tenis :
, a ponieważ .*
znajduje się wewnątrz grupy przechwytywania (.*)
, tekst ABC
jest zapisywany do grupy przechwytywania 1.
Numer grupy
Cały wzorzec jest zdefiniowany jako grupa o numerze 0.
Dowolna grupa przechwytywania we wzorcu rozpoczyna indeksowanie od 1. Indeksy są definiowane przez kolejność nawiasów otwierających grup przechwytywania . Jako przykład, oto wszystkie 5 grup przechwytywania według poniższego wzoru:
(group)(?:non-capturing-group)(g(?:ro|u)p( (nested)inside)(another)group)(?=assertion)
| | | | | | || | |
1-----1 | | 4------4 |5-------5 |
| 3---------------3 |
2-----------------------------------------2
Numery grup są używane w odwołaniach wstecznych \n
we wzorcu i $n
w łańcuchu zastępczym.
W innych odmianach wyrażeń regularnych (PCRE, Perl) można ich również używać w wywołaniach podprogramów .
Możesz uzyskać dostęp do tekstu dopasowanego do określonej grupy za pomocą Matcher.group(int group)
. Numery grup można zidentyfikować za pomocą powyższej zasady.
W niektórych odmianach wyrażeń regularnych (PCRE, Perl) dostępna jest funkcja resetowania gałęzi, która umożliwia użycie tej samej liczby do przechwytywania grup w różnych gałęziach naprzemienności .
Nazwa grupy
W języku Java 7 można zdefiniować nazwaną grupę przechwytywania (?<name>pattern)
i uzyskać dostęp do dopasowanej treści Matcher.group(String name)
. Wyrażenie regularne jest dłuższe, ale kod jest bardziej znaczący, ponieważ wskazuje, co próbujesz dopasować lub wyodrębnić za pomocą wyrażenia regularnego.
Nazwy grup są używane w odwołaniach wstecznych \k<name>
we wzorcu i ${name}
w łańcuchu zastępczym.
Nazwane grupy przechwytywania są nadal numerowane za pomocą tego samego schematu numerowania, więc można do nich również uzyskać dostęp za pośrednictwem Matcher.group(int group)
.
Wewnętrznie implementacja Javy po prostu odwzorowuje nazwę na numer grupy. Dlatego nie możesz użyć tej samej nazwy dla 2 różnych grup przechwytywania.
Dla reszty z nas
Oto prosty i jasny przykład tego, jak to działa
Regex:
([a-zA-Z0-9]+)([\s]+)([a-zA-Z ]+)([\s]+)([0-9]+)
Strunowy:
"!* UserName10 John Smith 01123 *!"
Jak widać, utworzyłem PIĘĆ grup, z których każda jest umieszczona w nawiasach.
Dołączyłem! * I *! po obu stronach, aby było jaśniejsze. Zwróć uwagę, że żaden z tych znaków nie znajduje się w wyrażeniu regularnym i dlatego nie zostanie wyświetlony w wynikach. Grupa (0) podaje tylko cały pasujący ciąg (wszystkie moje kryteria wyszukiwania w jednym wierszu). Grupa 1 zatrzymuje się tuż przed pierwszą spacją, ponieważ znak spacji nie został uwzględniony w kryteriach wyszukiwania. Grupy 2 i 4 to po prostu spacja, która w tym przypadku jest dosłownie spacją, ale może być również tabulatorem lub wysuwem wiersza itp. Grupa 3 zawiera spację, ponieważ umieściłem ją w kryteriach wyszukiwania ... itd.
Mam nadzieję, że to ma sens.
źródło
Nawiasy
()
służą do grupowania wyrażeń regularnych.group(1)
Zawiera ciąg znaków, który jest między nawiasami(.*)
więc.*
w tym przypadkuI
group(0)
zawiera cały dopasowany ciąg.Gdybyś miał więcej grup (czytaj
(...)
), zostałby podzielony na grupy z następnymi indeksami (2, 3 itd.).źródło