Szukaj…


Podstawowe grupy przechwytywania

Grupa to sekcja wyrażenia regularnego zawarta w nawiasach () . Jest to powszechnie nazywane „podwyrażeniem” i służy dwóm celom:

  • Powoduje, że podwyrażenie jest atomowe, tzn. Będzie albo pasować, zawieść, albo powtarzać jako całość.
  • Część dopasowanego tekstu jest dostępna w pozostałej części wyrażenia i pozostałej części programu.

Grupy są ponumerowane w silnikach wyrażeń regularnych, zaczynając od 1. Tradycyjnie maksymalna liczba grup wynosi 9, ale wiele współczesnych smaków wyrażeń regularnych obsługuje większą liczbę grup. Grupa 0 zawsze pasuje do całego wzorca, podobnie jak otaczanie całego wyrażenia regularnego za pomocą nawiasów.

Liczba porządkowa rośnie z każdym otwierającym nawiasiem, niezależnie od tego, czy grupy są umieszczane jedna po drugiej, czy zagnieżdżone:

foo(bar(baz)?) (qux)+|(bla)
   1   2       3      4

grupy i ich liczby

Gdy wyrażenie osiągnie ogólne dopasowanie, wszystkie jego grupy będą w użyciu - niezależnie od tego, czy dana grupa zdołała coś dopasować, czy nie.

Grupa może być opcjonalna, np. (baz)? powyżej lub w alternatywnej części wyrażenia, które nie zostało użyte w dopasowaniu, np. (bla) powyżej. W takich przypadkach niepasujące grupy po prostu nie będą zawierać żadnych informacji.

Jeśli kwantyfikator jest umieszczony za grupą, jak w (qux)+ powyżej, ogólna liczba grup wyrażeń pozostaje taka sama. Jeśli grupa pasuje więcej niż jeden raz, jej zawartość będzie ostatnim wystąpieniem dopasowania. Jednak nowoczesne smaki regex pozwalają na dostęp do wszystkich wystąpień pod meczem.


Jeśli chcesz pobrać datę i poziom błędu wpisu dziennika, taki jak ten:

2012-06-06 12:12.014 ERROR: Failed to connect to remote end

Możesz użyć czegoś takiego:

^(\d{4}-\d{2}-\d{2}) \d{2}:\d{2}.\d{3} (\w*): .*$

Wyodrębniłoby to datę wpisu w dzienniku 2012-06-06 jako grupę przechwytywania 1 i poziom błędu ERROR jako grupę przechwytywania 2.

Referencje zwrotne i grupy nie przechwytujące

Ponieważ grupy są „ponumerowane”, niektóre silniki obsługują również dopasowanie do tego, co grupa wcześniej dopasowała ponownie.

Zakładając, że chcesz dopasować coś, w którym dwa równe ciągi długości trzy są podzielone przez $ , którego użyjesz:

(.{3})\$\1

To pasowałoby do dowolnego z następujących ciągów:

"abc$abc"
"a b$a b"
"af $af "
"   $   "

Jeśli chcesz, aby grupa nie była numerowana przez silnik, możesz zadeklarować, że grupa nie jest przechwytywana. Grupa nie przechwytująca wygląda następująco:

(?:)

Są one szczególnie przydatne do powtarzania określonego wzorca dowolną liczbę razy, ponieważ grupę można również wykorzystać jako „atom”. Rozważać:

(\d{4}(?:-\d{2}){2} \d{2}:\d{2}.\d{3}) (.*)[\r\n]+\1 \2

Spowoduje to dopasowanie dwóch wpisów rejestrowania w sąsiednich wierszach, które mają ten sam znacznik czasu i ten sam wpis.

Nazwane grupy przechwytywania

Niektóre smaki wyrażeń regularnych pozwalają na nazwane grupy przechwytywania . Zamiast indeksu numerycznego można odwoływać się do tych grup po nazwie w kolejnym kodzie, tj. W referencjach wstecznych, we wzorcu zastępowania, a także w kolejnych wierszach programu.

Indeksy numeryczne zmieniają się wraz ze zmianą liczby lub układu grup w wyrażeniu, więc są bardziej kruche w porównaniu.

Na przykład, aby dopasować słowo ( \w+ ) ujęte w pojedyncze lub podwójne cudzysłowy ( ['"] ), możemy użyć:

(?<quote>['"])\w+\k{quote}

Co odpowiada:

(['"])\w+\1

W takiej prostej sytuacji zwykła, numerowana grupa przechwytująca nie ma żadnych wad.

W bardziej złożonych sytuacjach użycie nazwanych grup sprawi, że struktura wyrażenia będzie bardziej czytelna dla czytelnika, co poprawi łatwość konserwacji.

Analiza pliku dziennika jest przykładem bardziej złożonej sytuacji korzystającej z nazw grup. Oto wspólny format dziennika Apache (CLF):

127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326

Poniższe wyrażenie ujmuje części w nazwane grupy:

(?<ip>\S+) (?<logname>\S+) (?<user>\S+) (?<time>\[[^]]+\]) (?<request>"[^"]+") (?<status>\S+) (?<bytes>\S+)

Składnia zależy od smaku, typowe to:

  • (?<name>...)
  • (?'name'...)
  • (?P<name>...)

Referencje:

  • \k<name>
  • \k{name}
  • \k'name'
  • \g{name}
  • (?P=name)

W smaku .NET możesz mieć kilka grup o tej samej nazwie, będą one używać stosów przechwytywania .

W PCRE musisz to wyraźnie włączyć za pomocą modyfikatora (?J) ( PCRE_DUPNAMES ) lub za pomocą grupy resetowania gałęzi (?|) . Dostępna będzie tylko ostatnia zarejestrowana wartość.

(?J)(?<a>...)(?<a>...)
(?|(?<a>...)|(?<a>...))


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow