Nie będziesz pierwszym, który się o tym myśli. Oto, co na ten temat ma do powiedzenia słynny Jeffrey Friedl (strony 437+):
W zależności od twojego poglądu, albo dodaje interesujący nowy wymiar do wyników meczu, albo dodaje zamieszania i wzdęcia.
I dalej:
Główna różnica między obiektem Group a obiektem Capture polega na tym, że każdy obiekt Group zawiera kolekcję przechwyceń reprezentujących wszystkie pośrednie dopasowania grupy podczas dopasowania, a także ostateczny tekst dopasowany przez grupę.
A kilka stron dalej, oto jego wniosek:
Po obejrzeniu dokumentacji .NET i zrozumieniu, co dodają te obiekty, mam co do nich mieszane uczucia. Z jednej strony jest to interesująca innowacja […], z drugiej strony wydaje się, że zwiększa wydajność […] funkcjonalności, która nie będzie używana w większości przypadków
Innymi słowy: są bardzo podobne, ale czasami i tak się składa, że znajdziesz dla nich zastosowanie. Zanim zapuścisz kolejną siwą brodę, możesz nawet polubić Capture ...
Ponieważ ani powyższe, ani to, co zostało powiedziane w innym poście, nie wydaje się odpowiadać na Twoje pytanie, rozważ następujące kwestie. Potraktuj Captures jako swego rodzaju narzędzie do śledzenia historii. Kiedy wyrażenie regularne dopasowuje się, przechodzi przez ciąg od lewej do prawej (ignorując na chwilę cofanie się), a kiedy napotka pasujące nawiasy przechwytujące, zapisze to w $x
(powiedzmy, że x jest dowolną cyfrą) $1
.
Normalne silniki wyrażeń regularnych, gdy mają zostać powtórzone nawiasy przechwytujące, odrzucą bieżący $1
i zastąpią go nową wartością. Nie .NET, który zachowa tę historię i umieści ją w Captures[0]
.
Jeśli zmienimy Twoje wyrażenie regularne, aby wyglądało następująco:
MatchCollection matches = Regex.Matches("{Q}{R}{S}", @"(\{[A-Z]\})+");
Zauważysz, że pierwsza Group
będzie miała jedną Captures
(pierwsza grupa to zawsze cały mecz, czyli równa się $0
), a druga grupa {S}
, czyli tylko ostatnia pasująca grupa. Jednak, a oto haczyk, jeśli chcesz znaleźć pozostałe dwa haczyki, są one w Captures
, które zawierają wszystkie pośrednie przechwytywania dla {Q}
{R}
i{S}
.
Jeśli kiedykolwiek zastanawiałeś się, w jaki sposób można uzyskać z wielokrotnego przechwytywania, które pokazuje tylko ostatnie dopasowanie do pojedynczych przechwyceń, które są wyraźnie widoczne w ciągu, musisz użyć Captures
.
Ostatnie słowo na twoje ostatnie pytanie: całkowite dopasowanie zawsze ma jedno całkowite przejęcie, nie mieszaj tego z poszczególnymi grupami. Zrzuty są interesujące tylko w grupach .
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.(?:..)+
. Łagodnie dopasuj wszystko.*?
do wyrażenia podrzędnego przechwytywania (grupy). Kontynuuj. W ramach jednego dopasowania zbiór grupowy generuje tablicę dokładnie tego, co jest potrzebne. Nie ma potrzeby znajdowania następnego, nie ma ponownego wejścia, dzięki czemu jest 10 do 20 lub więcej razy szybciej.a functionality that won't be used in the majority of cases
. W rzeczywistości jest to najbardziej poszukiwana funkcja w krainie wyrażeń regularnych. Leniwy / chciwy? Co to ma wspólnego z moimi komentarzami? Umożliwia to posiadanie zmiennej ilości buforów przechwytywania. Może zamiatać cały ciąg w jednym meczu. Jeśli.*?(dog)
znajdzie pierwszydog
wtedy(?:.*?(dog))+
znajdzie wszystkodog
w cały ciąg w jednym meczu. Wzrost wydajności jest zauważalny.Grupa jest tym, co skojarzyliśmy z grupami w wyrażeniach regularnych
poza tym, że są to tylko grupy „przechwycone”. Grupy bez przechwytywania (przy użyciu składni „(?:”) Nie są tutaj reprezentowane.
Przechwytywanie jest również tym, co skojarzyliśmy z „przechwyconymi grupami”. Ale gdy grupa jest wielokrotnie stosowana z kwantyfikatorem, tylko ostatnie dopasowanie jest zachowywane jako dopasowanie grupy. Tablica przechwytywania przechowuje wszystkie te dopasowania.
A jeśli chodzi o twoje ostatnie pytanie - zanim się nad tym zastanowiłem, pomyślałem, że przechwytywania będą tablicą ujęć uporządkowanych według grupy, do której należą. Jest to raczej alias do grup [0] .Przechwytuje. Całkiem bezużyteczne ...
źródło
Można to wytłumaczyć prostym przykładem (i ilustracjami).
Dopasowanie
3:10pm
do wyrażenia regularnego((\d)+):((\d)+)(am|pm)
i użycie interaktywnej Monocsharp
:Więc gdzie jest 1?
Ponieważ istnieje wiele cyfr pasujących do czwartej grupy, „uzyskujemy” tylko ostatnie dopasowanie, jeśli odwołujemy się do grupy (to
ToString()
znaczy niejawnie ). Aby ujawnić dopasowania pośrednie, musimy wejść głębiej i odwołać się doCaptures
właściwości w danej grupie:Dzięki uprzejmości tego artykułu .
źródło
Z dokumentacji MSDN :
źródło
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.Wyjście :
Przeanalizujmy tylko pierwsze dopasowanie (
match0
).Jak widać istnieją trzy grupy drobne :
group3
,group4
igroup5
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 przypadkugroup4
igroup5
). 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:
Ponownie przeanalizujmy tylko pierwsze dopasowanie (
match0
).Nie ma już mniejszych grup
group4
izgroup5
powodu(...){3}
powtórzeń ( {n} gdzie n> = 2 ) zostały połączone w jedną grupęgroup3
.W tym przypadku
group3
wartość odpowiada itcapture2
( 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 .
źródło