Wzorzec (Java Platform SE 7)

Skompilowana reprezentacja wyrażenia regularnego.

Wyrażenie regularne określone jako ciąg znaków musi najpierw zostać wkompilowane w instancję tej klasy. Powstały wzorzec można następnie wykorzystać do utworzenia obiektu Matcher, który może pasować do dowolnej sekwencji znaków przeciwko wyrażeniu regularnemu. Cały stan zaangażowany w dopasowanie znajduje się w dopasowywaniu, więc wiele dopasowań może współdzielić ten sam wzorzec.

Typowa sekwencja wywołania to

 Pattern p = Pattern.
("a*b"); Matcher m = p.
("aaaaab"); boolean b = m.
();

Metoda matches jest zdefiniowana przez tę klasę jako ułatwienie w przypadku jednorazowego użycia wyrażenia regularnego. Ta metoda kompiluje wyrażenie i dopasowuje do niego sekwencję wejściową w jednym wywołaniu. Instrukcja

 boolean b = Pattern.matches("a*b", "aaaaab");

jest odpowiednikiem trzech powyższych stwierdzeń, chociaż dla powtarzających się dopasowań jest mniej efektywny, ponieważ nie pozwala na ponowne użycie skompilowanego wzorca.

Wystąpienia tej klasy są niezmienne i można ich bezpiecznie używać przez wiele współbieżnych wątków. Wystąpienia klasy Matcher nie są bezpieczne do takiego użycia.

Podsumowanie konstrukcji wyrażeń regularnych

Ukośniki odwrotne, znaki specjalne i cytowanie

Znak ukośnika odwrotnego („\”) służy do wprowadzania konstrukcji ze zmienną ucieczką, jak zdefiniowano w powyższa tabela, a także cytowanie znaków, które w przeciwnym razie byłyby interpretowane jako konstrukcje bez znaku zmiany znaczenia. Zatem wyrażenie \\ dopasowuje pojedynczy ukośnik odwrotny, a \ {dopasowuje lewy nawias.

Błędem jest użycie ukośnika odwrotnego przed jakimkolwiek znakiem alfabetu, który nie oznacza konstrukcji ze zmienioną wartością; są one zarezerwowane dla przyszłych rozszerzeń języka wyrażeń regularnych. Odwrotnego ukośnika można użyć przed znakiem niealfabetycznym, niezależnie od tego, czy ten znak jest częścią konstrukcji bez znaku zmiany znaczenia.

Ukośniki odwrotne w literałach ciągów w kodzie źródłowym Java są interpretowane zgodnie z wymaganiami Specyfikacji języka Java ™ jako znaki specjalne Unicode (sekcja 3.3) lub inne znaki ucieczki (sekcja 3.10.6) Dlatego konieczne jest podwójne ukośniki odwrotne w literałach łańcuchowych, które reprezentują wyrażenia regularne, aby chronić je przed interpretacją przez kompilator kodu bajtowego Java. Na przykład literał ciągu „\ b” dopasowuje pojedynczy znak cofania, gdy jest interpretowany jako wyrażenie regularne, a „\\ b” odpowiada granicy słowa. Literał „\ (hello \)” jest niedozwolony i prowadzi do błędu w czasie kompilacji; aby dopasować ciąg (witaj), należy użyć literału ciągu „\\ (witaj \\)”.

Klasy znaków

Klasy znaków mogą występować w innych klasach znaków i mogą być tworzone przez operator sumy (niejawny) i operator przecięcia (& &). Operator unii oznacza klasę, która zawiera każdy znak, który jest w co najmniej jednej z jej klas operandów. Operator przecięcia oznacza klasę, która zawiera każdy znak znajdujący się w obu klasach operandów.

Pierwszeństwo operatorów klasy znaków jest następujące, od najwyższej do najniższej:

1 Dosłowne ucieczki \ x
2 Grupowanie
3 Zakres az
4 Unia
5 Przecięcie ]

Zauważ, że inny zestaw metaznaków działa wewnątrz klasy znaków niż poza klasa postaci. Na przykład wyrażenie regularne. traci swoje szczególne znaczenie wewnątrz klasy znaków, a wyrażenie – staje się zakresem tworzącym metaznak.

Terminatory linii

Terminator linii to jedno- lub dwuznakowa sekwencja, która oznacza koniec wiersza w wejściowej sekwencji znaków. Następujące elementy są rozpoznawane jako zakończenia linii:

Jeśli tryb UNIX_LINES jest włączony, jedynymi rozpoznawanymi znakami zakończenia linii są znaki nowej linii.

Wyrażenie regularne. dopasowuje dowolny znak poza zakończeniem wiersza, chyba że określono flagę DOTALL.

Domyślnie wyrażenia regularne ^ i $ ignorują zakończenia wierszy i dopasowują tylko odpowiednio na początku i na końcu całej sekwencji wejściowej. Jeśli tryb MULTILINE jest aktywowany, wtedy znak ^ dopasowuje na początku wejścia i po dowolnym zakończeniu linii, z wyjątkiem końca wejścia. W trybie MULTILINE $ dopasowuje się tuż przed zakończeniem linii lub końcem sekwencji wejściowej.

Grupy i przechwytywanie

Numer grupy

Grupy przechwytywania są numerowane, licząc nawiasy otwierające od lewej do prawej.Na przykład w wyrażeniu ((A) (B (C))) istnieją cztery takie grupy:

1

((A) (B (C)))

2

(A)

3

(B (C))

4

(C)

Grupa zero zawsze oznacza całe wyrażenie.

Grupy przechwytywania są tak nazwane, ponieważ podczas dopasowania zapisywany jest każdy podciąg sekwencji wejściowej, który pasuje do takiej grupy. Przechwycona sekwencja może być użyta później w wyrażeniu, poprzez odniesienie wsteczne, a także może zostać pobrana z elementu dopasowującego po zakończeniu operacji dopasowania.

Nazwa grupy

Grupie przechwytywania można również przypisać „nazwę”, nazwaną grupę przechwytującą, a następnie odwołać się do niej później za pomocą „nazwy”. Nazwy grup składają się z następujących znaków. Pierwszy znak musi być literą.

Nazwana grupa przechwytująca jest nadal numerowana zgodnie z opisem w Numer grupy.

Przechwycone dane wejściowe skojarzone z grupą są zawsze podciągami, które ostatnio dopasowała grupa. Jeśli grupa jest oceniana po raz drugi z powodu kwantyfikacji, wówczas jej poprzednio uchwycona wartość, jeśli taka istnieje, zostanie zachowana, jeśli druga ocena nie powiedzie się. Na przykład dopasowanie ciągu „aba” do wyrażenia (a (b)?) + Pozostawia grupę drugą ustawioną na „b”. Wszystkie przechwycone dane wejściowe są odrzucane na początku każdego dopasowania.

Grupy zaczynające się od (? są czystymi grupami bez przechwytywania, które nie przechwytują tekstu i nie są wliczane do całej grupy, lub grupą przechwytującą o nazwie.

Obsługa Unicode

Ta klasa jest zgodna z poziomem 1 standardu technicznego Unicode nr 18: Wyrażenie regularne Unicode oraz odpowiedniki kanoniczne RL2.1.

Sekwencje unikowe Unicode, takie jak \ u2014 w kodzie źródłowym Java są przetwarzane zgodnie z opisem w sekcji 3.3 specyfikacji języka Java ™. Takie sekwencje specjalne są również implementowane bezpośrednio przez parser wyrażeń regularnych, dzięki czemu znaki unikodowe mogą być używane w wyrażeniach odczytywanych z plików lub z klawiatury. W ten sposób ciągi „” \ u2014 „i” \\ u2014 „, chociaż nie są równe, kompilują się do tego samego wzorca, który dopasowuje znak o wartości szesnastkowej 0x2014.

Znak Unicode można również przedstawić w wyrażeniu regularnym za pomocą jego zapis szesnastkowy (szesnastkowa wartość punktu kodowego) bezpośrednio, jak opisano w konstrukcji \ x {…}, for na przykład znak uzupełniający U + 2011F można określić jako \ x {2011F} zamiast dwóch kolejnych sekwencji unikowych Unicode pary zastępczej \ uD840 \ uDD1F.

Skrypty, bloki, kategorie i właściwości binarne Unicode są zapisywane za pomocą konstrukcji \ p i \ P, tak jak w Perlu. \ p {prop} pasuje, jeśli wejście ma właściwość prop, podczas gdy \ P {prop} nie pasuje, jeśli wejście ma tę właściwość.

Skrypty, bloki, kategorie i właściwości binarne mogą być używane zarówno wewnątrz, jak i na zewnątrz klasy znaków.

Skrypty są określane za pomocą przedrostka Is, tak jak w IsHiragana, lub za pomocą (lub jego krótka forma sc), jak w script=Hiragana lub sc=Hiragana.

Nazwy skryptów obsługiwane przez Pattern to prawidłowe nazwy skryptów akceptowane i definiowane przez UnicodeScript.forName.

Bloki są określane za pomocą przedrostka In, jak w InMongolian, lub za pomocą słowa kluczowego block (lub jego krótka forma blk) jak w block=Mongolian lub blk=Mongolian.

Nazwy bloków obsługiwane przez Pattern to prawidłowe nazwy bloków akceptowane i definiowane przez UnicodeBlock.forName.

Kategorie można określić z opcjonalnym prefiksem Is: Zarówno \p{L}, jak i \p{IsL} oznacza kategorię liter Unicode. Podobnie jak w przypadku skryptów i bloków, kategorie można również określić za pomocą słowa kluczowego general_category (lub jego krótkiej formy gc), jak w general_category=Lu lub gc=Lu.

Obsługiwane kategorie to te ze standardu Unicode w wersji określonej przez klasę Character. Nazwy kategorii to te zdefiniowane w standardzie, zarówno normatywne, jak i informacyjne.

Właściwości binarne są określane za pomocą przedrostka Is, jak w IsAlphabetic.Obsługiwane właściwości binarne przez Pattern to

  • Alphabetic
  • Ideographic
  • Letter
  • Małe litery
  • Wielkie litery
  • Wielkie litery
  • Interpunkcja
  • Kontrolka
  • Biała_spacja
  • Cyfra
  • Hex_Digit
  • Noncharacter_Code_Point
  • Przypisane

Predefiniowane klasy znaków i klasy znaków POSIX są zgodne z zaleceniami Załącznik C: Właściwości zgodności wyrażeń regularnych Unicode, gdy określono flagę UNICODE_CHARACTER_CLASS.

Kategorie, które zachowują się jak metody java.lang.Character boolean ismethodname (z wyjątkiem przestarzałych), są dostępne za pomocą tej samej składni \ p {prop}, w której określona właściwość ma nazwę javamethodname.

Porównanie z Perlem 5

Silnik Pattern wykonuje tradycyjne dopasowywanie oparte na NFA z uporządkowaną przemianą, jak ma to miejsce w Perlu 5.

Konstrukcje Perla nieobsługiwane przez tę klasę:

Konstrukcje obsługiwane przez tę klasę, ale nie przez Perl:

  • Połączenie i przecięcie klasy znaków zgodnie z opisem powyżej.

Znaczące różnice w porównaniu z Perlem:

  • W Perlu, \ 1 do \ 9 są zawsze interpretowane jako odniesienia wsteczne; liczba większa niż 9 ze ucieczką odwrotną jest traktowana jako odniesienie wsteczne, jeśli istnieje przynajmniej tyle podwyrażeń, w przeciwnym razie jest interpretowana, jeśli to możliwe, jako ósemkowa ucieczka. W tej klasie ucieczki ósemkowe muszą zawsze zaczynać się od zera. W tej klasie \ 1 do \ 9 są zawsze interpretowane jako odniesienia wsteczne, a większa liczba jest akceptowana jako odniesienie wsteczne, jeśli przynajmniej tyle podwyrażeń istnieje w tym punkcie wyrażenia regularnego, w przeciwnym razie parser usunie cyfry do liczby jest mniejsza lub równa istniejącej liczbie grup lub jest jedną cyfrą.

  • Perl używa flagi g, aby zażądać dopasowania, które jest kontynuowane w miejscu, w którym zostało przerwane ostatnie dopasowanie. Ta funkcja jest udostępniana niejawnie przez klasę Matcher: powtarzające się wywołania metody find zostaną wznowione w miejscu, w którym zakończyło się ostatnie dopasowanie, chyba że element dopasowujący jest resetowany.

  • W Perlu flagi osadzone na najwyższym poziomie wyrażenia wpływają na całe wyrażenie. W tej klasie flagi osadzone zawsze działają w miejscu, w którym się pojawiają, niezależnie od tego, czy znajdują się na najwyższym poziomie, czy w grupie; w tym drugim przypadku flagi są przywracane na końcu grupy, tak jak w Perlu.

Bardziej precyzyjny opis zachowania konstrukcji wyrażeń regularnych można znaleźć w książce Mastering Regular Expressions, 3. wydanie, Jeffrey EF Friedl, O „Reilly and Associates, 2006.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *