Wyobraź sobie, że wprowadzasz następujący tekst dogcatcatcat
i wzór podobny dodog(cat(catcat))
W tym przypadku masz 3 grupy, pierwszą ( główną ) odpowiada dopasowaniu.
Dopasuj == dogcatcatcat
i Grupa0 ==dogcatcatcat
Grupa1 == catcatcat
Grupa2 == catcat
Więc o co w tym wszystkim chodzi?
Rozważmy mały przykład napisany w C # (.NET) przy użyciu Regex
class.
int matchIndex = 0;
int groupIndex = 0;
int captureIndex = 0;
foreach (Match match in Regex.Matches(
"dogcatabcdefghidogcatkjlmnopqr", // input
@"(dog(cat(...)(...)(...)))") // pattern
)
{
Console.Out.WriteLine($"match{matchIndex++} = {match}");
foreach (Group @group in match.Groups)
{
Console.Out.WriteLine($"\tgroup{groupIndex++} = {@group}");
foreach (Capture capture in @group.Captures)
{
Console.Out.WriteLine($"\t\tcapture{captureIndex++} = {capture}");
}
captureIndex = 0;
}
groupIndex = 0;
Console.Out.WriteLine();
}
Wyjście :
match0 = dogcatabcdefghi
group0 = dogcatabcdefghi
capture0 = dogcatabcdefghi
group1 = dogcatabcdefghi
capture0 = dogcatabcdefghi
group2 = catabcdefghi
capture0 = catabcdefghi
group3 = abc
capture0 = abc
group4 = def
capture0 = def
group5 = ghi
capture0 = ghi
match1 = dogcatkjlmnopqr
group0 = dogcatkjlmnopqr
capture0 = dogcatkjlmnopqr
group1 = dogcatkjlmnopqr
capture0 = dogcatkjlmnopqr
group2 = catkjlmnopqr
capture0 = catkjlmnopqr
group3 = kjl
capture0 = kjl
group4 = mno
capture0 = mno
group5 = pqr
capture0 = pqr
Przeanalizujmy tylko pierwsze dopasowanie (match0
).
Jak widać istnieją trzy grupy drobne : group3
, group4
igroup5
group3 = kjl
capture0 = kjl
group4 = mno
capture0 = mno
group5 = pqr
capture0 = pqr
Te grupy (3-5) powstały z powodu „ podciąg wzorca ” (...)(...)(...)
w głównej strukturze (dog(cat(...)(...)(...)))
Wartość group3
odpowiada jego przechwytywaniu ( capture0
). (Jak w przypadku group4
i group5
). To dlatego, że nie ma takich powtórzeń grupowych(...){3}
.
Ok, rozważmy inny przykład, w którym występuje powtórzenie grupowe .
Jeśli zmodyfikujemy wzorzec wyrażenia regularnego, który ma być dopasowany (dla kodu pokazanego powyżej) od (dog(cat(...)(...)(...)))
do (dog(cat(...){3}))
, zauważysz, że występuje następujące powtórzenie grupy :(...){3}
.
Teraz wyjściowa uległa zmianie:
match0 = dogcatabcdefghi
group0 = dogcatabcdefghi
capture0 = dogcatabcdefghi
group1 = dogcatabcdefghi
capture0 = dogcatabcdefghi
group2 = catabcdefghi
capture0 = catabcdefghi
group3 = ghi
capture0 = abc
capture1 = def
capture2 = ghi
match1 = dogcatkjlmnopqr
group0 = dogcatkjlmnopqr
capture0 = dogcatkjlmnopqr
group1 = dogcatkjlmnopqr
capture0 = dogcatkjlmnopqr
group2 = catkjlmnopqr
capture0 = catkjlmnopqr
group3 = pqr
capture0 = kjl
capture1 = mno
capture2 = pqr
Ponownie przeanalizujmy tylko pierwsze dopasowanie (match0
).
Nie ma już mniejszych grup group4
iz group5
powodu (...){3}
powtórzeń ( {n} gdzie n> = 2 ) zostały połączone w jedną grupęgroup3
.
W tym przypadku group3
wartość odpowiada it capture2
( ostatnie przechwycenie innymi słowy ).
Tak więc, jeśli chcesz wszystkie 3 wewnętrzne oddaje ( capture0
, capture1
, capture2
) będziesz musiał przechodzić GRUPYCaptures
kolekcji.
Wniosek jest następujący: zwróć uwagę na sposób projektowania grup wzoru. Należy pomyśleć z góry, co powoduje zachowanie specyfikacji grupy, jak (...)(...)
, (...){2}
lub (.{3}){2}
etc.
Miejmy nadzieję, że pomoże to rzucić nieco światła na różnice między przejęciami , grupami i meczami .
a functionality that won't be used in the majority of cases
Myślę, że przegapił łódź. W krótkim okresie(?:.*?(collection info)){4,20}
zwiększa efektywność o kilkaset procent.