Wyrażenia regularne zgodne z Perlem - Perl Compatible Regular Expressions

Wyrażenia regularne zgodne z Perlem
Pierwotny autor (autorzy) Filip Hazel
Wersja stabilna
PCRE2 10.38 i PCRE 8.45 / 15 czerwca 2021 ; 3 miesiące temu ( 2021-06-15 )
Magazyn
Napisane w C
System operacyjny Wieloplatformowy
Rodzaj Biblioteka dopasowania wzorców
Licencja BSD
Strona internetowa www.pcre.org

Perl Compatible Regular Expressions ( PCRE ) to biblioteka napisana w C , która implementuje silnik wyrażeń regularnych , inspirowany możliwościami języka programowania Perl . Philip Hazel zaczął pisać PCRE latem 1997 roku. Składnia PCRE jest znacznie bardziej wydajna i elastyczna niż którykolwiek ze smaków wyrażeń regularnych POSIX (BRE, ERE) oraz niż wiele innych bibliotek wyrażeń regularnych.

Chociaż PCRE pierwotnie miało na celu równoważność funkcji z Perlem, te dwie implementacje nie są w pełni równoważne. Podczas fazy PCRE 7.x i Perl 5.9.x oba projekty koordynowały rozwój, a funkcje były przenoszone między nimi w obu kierunkach.

W 2015 roku został wydany fork PCRE ze zmienionym interfejsem programistycznym (API). Oryginalne oprogramowanie, teraz nazwane PCRE1 (seria 8.xx), miało naprawione błędy, ale nie było dalej rozwijane. Jest teraz (2020) uważany za przestarzały, a obecne wydanie 8.45 będzie prawdopodobnie ostatnim. Nowy kod PCRE2 (seria 10.xx) ma wiele rozszerzeń i ulepszeń kodowania i jest miejscem, w którym odbywa się rozwój.

Wiele znanych programów typu open source , takich jak serwery HTTP Apache i Nginx oraz języki skryptowe PHP i R , zawiera bibliotekę PCRE; oprogramowanie własnościowe może zrobić to samo, ponieważ biblioteka jest licencjonowana przez BSD. Od wersji Perl 5.10, PCRE jest również dostępny jako zamiennik domyślnego silnika wyrażeń regularnych Perla za pośrednictwem re::engine::PCREmodułu.

Bibliotekę można zbudować w systemach Unix, Windows i kilku innych środowiskach. PCRE2 jest rozprowadzany z opakowaniem POSIX C, kilkoma programami testowymi i programem narzędziowym `pcre2grep` wbudowanym w tandemie z biblioteką.

Cechy

Obsługa kompilatora just-in-time

Ta opcjonalna funkcja jest dostępna, jeśli jest włączona, gdy budowana jest biblioteka PCRE2. Duże korzyści w zakresie wydajności są możliwe, gdy (na przykład) program wywołujący wykorzystuje funkcję ze zgodnymi wzorcami, które są wykonywane wielokrotnie. Obsługa kompilatora just-in-time została napisana przez Zoltana Herczega i nie jest adresowana w wrapperze POSIX.

Elastyczne zarządzanie pamięcią

Wykorzystanie stosu systemowego do backtrackingu może być problematyczne w PCRE1, dlatego w PCRE2 zmieniono tę cechę implementacji. Sterta jest teraz wykorzystywana do tego celu, a łączną ilość można ograniczyć. Problem przepełnienia stosu , który pojawiał się regularnie w PCRE1, nie jest już problemem w PCRE2 od wydania 10.30 (2017).

Spójne zasady ucieczki

Podobnie jak Perl, PCRE2 ma spójne reguły ucieczki: każdy znak niealfanumeryczny może zostać zmieniony, aby oznaczał jego wartość dosłowną, poprzedzony znakiem \ukośnika odwrotnego (backslash). Każdy znak alfanumeryczny poprzedzony ukośnikiem odwrotnym zwykle nadaje mu specjalne znaczenie. W przypadku, gdy sekwencja nie została zdefiniowana jako specjalna, pojawia się błąd. Różni się to od Perla, który wyświetla błąd tylko wtedy, gdy jest w trybie ostrzegawczym (PCRE2 nie ma trybu ostrzegawczego). W podstawowych wyrażeniach regularnych POSIX czasami odwrotne ukośniki wymykały się znakom niealfanumerycznym (np. \.), a czasami wprowadzały specjalną cechę (np \(\). ).

Rozszerzone klasy postaci

Oprócz dłuższych nazw POSIX obsługiwane są klasy znaków jednoliterowych . Na przykład \ddopasowuje dowolną cyfrę dokładnie tak, jak [[:digit:]]w wyrażeniach regularnych POSIX.

Minimalne dopasowanie (inaczej „niechciwy”)

A ?można umieścić po dowolnym kwantyfikatorze powtórzeń, aby wskazać, że należy użyć najkrótszego dopasowania. Domyślnie próbuje się najpierw najdłuższego dopasowania i cofa się przez krótsze dopasowania: np. a.*?bdopasuje "ab" do "ababab", gdzie a.*bdopasuje cały łańcuch.

Właściwości znaków Unicode

Unicode definiuje kilka właściwości dla każdego znaku. Wzorce w PCRE2 mogą pasować do tych właściwości: np. pasują do łańcucha rozpoczynającego się od dowolnej „interpunkcji otwierającej” i kończącej się „bliską interpunkcją”, taką jak . Dopasowanie pewnych „normalnych” metaznaków może być sterowane przez właściwości Unicode, gdy ustawiona jest opcja kompilacji PCRE2_UCP. Opcję można ustawić dla wzoru, dołączając na początku wzoru. Opcja zmienia zachowanie następujących metaznaków: , , , , , , , , oraz niektórych klas znaków POSIX. Na przykład zestaw znaków dopasowanych przez (znaki wyrazów) jest rozszerzany o litery i litery akcentowane zgodnie z definicją we właściwościach Unicode. Takie dopasowanie jest wolniejsze niż normalna ( tylko ASCII ) alternatywa bez UCP. Zauważ, że opcja UCP wymaga, aby biblioteka została zbudowana z obsługą Unicode (jest to ustawienie domyślne dla PCRE2). Bardzo wczesne wersje PCRE1 obsługiwały tylko kod ASCII. Później dodano obsługę UTF-8. Obsługa UTF-16 została dodana w wersji 8.30, a obsługa UTF-32 w wersji 8.32. PCRE2 zawsze obsługiwał wszystkie trzy kodowania UTF. \p{Ps}.*?\p{Pe}[abc](*UCP)\B\b\D\d\S\s\W\w\w

Dopasowanie wielowierszowe

^i $może pasować tylko na początku i na końcu ciągu lub na początku i na końcu każdej „linii” w ciągu, w zależności od ustawionych opcji.

Opcje nowej linii/przełamania linii

Podczas kompilacji PCRE wybierany jest domyślny znak nowej linii. To, który znak nowej linii/złamania linii jest aktywny, wpływa na to, gdzie PCRE wykrywa ^początek i $koniec linii (w trybie wielowierszowym), a także na to, co pasuje do kropki (niezależnie od trybu wielowierszowego, chyba że ustawiono opcję dotall (?s)). Ma to również wpływ na procedurę dopasowywania PCRE (od wersji 7.0): gdy niezakotwiczony wzorzec nie pasuje na początku sekwencji nowego wiersza, PCRE przechodzi przez całą sekwencję nowego wiersza przed ponowną próbą dopasowania. Jeśli alternatywa opcji nowej linii w efekcie zawiera CRLF jako jeden z poprawnych łamania linii, nie pomija \nznaku CRLF, jeśli wzorzec zawiera specyficzne \rlub \nodwołania (od wersji 7.3). Od wersji 8.10 metaznak \Nzawsze dopasowuje dowolny znak inny niż znaki łamania linii. .Zachowuje się tak samo, jak wtedy, gdy opcja dotall aka (?s)nie jest aktywna .

Opcja nowej linii może być zmieniona opcjami zewnętrznymi podczas kompilowania i uruchamiania PCRE. Niektóre aplikacje korzystające z PCRE zapewniają użytkownikom możliwość zastosowania tego ustawienia za pomocą opcji zewnętrznej. Tak więc opcję nowej linii można również podać na początku wzorca za pomocą jednego z poniższych:

  • (*LF)Nowa linia to znak wysuwu wiersza. Odpowiednie łamania wierszy można dopasować za pomocą \n.
  • (*CR)Newline to powrót karetki. Odpowiednie łamania wierszy można dopasować za pomocą \r.
  • (*CRLF)Nowy wiersz/złamanie wiersza to powrót karetki, po którym następuje wysunięcie wiersza. Odpowiednie łamania wierszy można dopasować za pomocą \r\n.
  • (*ANYCRLF)Każde z powyższych napotkanych w danych spowoduje uruchomienie przetwarzania nowego wiersza. Odpowiednie łamania wierszy można dopasować za pomocą lub za pomocą . Zobacz poniżej konfigurację i opcje dotyczące tego, co pasuje do odwrotnego ukośnika-R.(?:\r\n?|\n)\R
  • (*ANY) Każdy z powyższych plus specjalne łamania linii Unicode.

Gdy nie jest w trybie UTF-8, odpowiednie łamanie linii można dopasować za pomocą lub . (?:\r\n?|\n|\x0B|\f|\x85)\R

W trybie UTF-8 dwa dodatkowe znaki są rozpoznawane jako znaki końca linii (*ANY):

  • LS (separator linii, U+2028),
  • PS (separator akapitów, U+2029).

W systemie Windows, w danych innych niż Unicode, niektóre ANYznaki łamania linii mają inne znaczenie.

Na przykład \x85może pasować do poziomego wielokropka, a jeśli zostanie napotkany, gdy obowiązuje znak ANYnowej linii, uruchomi przetwarzanie nowego wiersza.

Zobacz poniżej konfigurację i opcje dotyczące tego, co pasuje do odwrotnego ukośnika-R.

Opcje odwrotnego ukośnika-R

Podczas kompilacji PCRE wybierana jest wartość domyślna dla tego, co pasuje \R. Wartością domyślną może być dopasowanie podziałów linii odpowiadających ANYCRLF lub tych odpowiadających ANY. W razie potrzeby wartość domyślną można nadpisać, dołączając (*BSR_UNICODE)lub (*BSR_ANYCRLF)na początku wzorca. Podając (*BSR..)opcję, możesz również podać opcję, np . . Opcje odwrotnego ukośnika-R można również zmienić za pomocą opcji zewnętrznych przez aplikację wywołującą PCRE2, podczas kompilacji wzorca. (*newline)(*BSR_UNICODE)(*ANY)rest-of-pattern

Początek opcji wzoru

Opcje łamania linii, takie jak (*LF)opisane powyżej; opcje odwrotnego ukośnika-R, takie jak (*BSR_ANYCRLF)opisane powyżej; Opcja Właściwości znaków Unicode (*UCP)udokumentowana powyżej; (*UTF8)opcja udokumentowana w następujący sposób: jeśli twoja biblioteka PCRE2 została skompilowana z obsługą UTF , możesz określić (*UTF)opcję na początku wzorca zamiast ustawiać opcję zewnętrzną, aby wywołać tryb UTF-8, UTF-16 lub UTF-32.

Referencje wsteczne

Wzór może odnosić się do wyników poprzedniego meczu. Na przykład (a|b)c\1pasowałby do „aca” lub „bcb” i nie pasowałby na przykład do „acb”.

Nazwane podwzorce

Wzorzec podrzędny (otoczony nawiasami, np. (...)) może być nazwany przez dołączenie wiodącego ?P<name>po nawiasie otwierającym. Nazwane podwzorce to funkcja, którą PCRE przejął z wyrażeń regularnych Pythona .

Ta funkcja została później zaadoptowana przez Perl, więc teraz nazwane grupy można również definiować za pomocą (?<name>...)lub (?'name'...), a także (?P<name>...). Do nazwanych grup można odwoływać się wstecz, na przykład: (?P=name)(składnia Pythona) lub \k'name'(składnia Perl).


Podprogramy

Podczas gdy odwołanie wsteczne zapewnia mechanizm odwoływania się do tej części podmiotu, która poprzednio pasowała do podwzorca, podprogram zapewnia mechanizm ponownego użycia bazowego wcześniej zdefiniowanego podwzorca. Opcje podwzorca, takie jak niezależność obserwacji, są ustalane podczas definiowania podwzorca. (a.c)(?1)dopasuje "aacabc" lub "abcadc", podczas gdy użycie odwołania wstecznego (a.c)\1nie, chociaż oba pasują do "aacaac" lub "abcabc". PCRE obsługuje również konstrukcję podprogramów inną niż Perl Oniguruma . Określa się je za pomocą \g<subpat-number>lub \g<subpat-name>.

Grupowanie atomowe

Grupowanie atomowe to sposób na zapobieganie cofaniu się we wzorcu. Na przykład a++bcdopasuje jak najwięcej „a” i nigdy nie wykona kopii zapasowej, aby spróbować o jedno mniej.

Asercje wyprzedzające i wsteczne

Twierdzenie Spojrzeć za siebie Patrz przed siebie
Pozytywny (? <= wzór ) (? = wzór )
Negatywny (? <! wzór ) (? ! wzór )
Asercje wsteczne i wyprzedzające
w wyrażeniach regularnych Perla

Wzorce mogą twierdzić, że poprzedni tekst lub kolejny tekst zawiera wzorzec bez zużywania dopasowanego tekstu (potwierdzenie o zerowej szerokości). Na przykład / \w+(?=\t)/ dopasowuje słowo, po którym następuje tabulator , bez dołączania samej tabulatora.

Asercje patrzące w tył nie mogą mieć niepewnej długości (w przeciwieństwie do Perla) każda gałąź może mieć inną stałą długość.

\Kmoże być użyty we wzorcu, aby zresetować początek bieżącego całego meczu. Zapewnia to elastyczne alternatywne podejście do potwierdzeń wstecznych, ponieważ odrzucona część dopasowania (część poprzedzająca \K) nie musi mieć ustalonej długości.

Sekwencje ucieczki dla asercji o zerowej szerokości

Np. \bdo dopasowywania „granic słów” o zerowej szerokości, podobnie jak . (?<=\W)(?=\w)|(?<=\w)(?=\W)|^|$

Uwagi

Komentarz zaczyna się (?#i kończy następnym nawiasem zamykającym.

Wzory rekurencyjne

Wzorzec może odwoływać się do siebie rekurencyjnie lub do dowolnego podwzorca. Na przykład wzorzec będzie pasował do dowolnej kombinacji zrównoważonych nawiasów i „a”. \((a*|(?R))*\)

Objaśnienia ogólne

Wyrażenia PCRE można osadzać (?C''n''), gdzie n jest liczbą. To wywoła zewnętrzną funkcję zdefiniowaną przez użytkownika za pośrednictwem interfejsu API PCRE i może zostać użyte do osadzenia dowolnego kodu we wzorcu.

Różnice w stosunku do Perla

Różnice między PCRE2 i Perl (od Perl 5.9.4) obejmują między innymi:

Do czasu wydania 10.30 dopasowania rekurencyjne były atomowe w PCRE i nieatomowe w Perl

Oznaczało to, że będzie pasować w Perlu, ale nie w PCRE2 aż do wydania 10.30. "<<!>!>!>><>>!>!>!>" =~ /^(<(?:[^<>]+|(?3)|(?1))*>)()(!>!>!>)$/

Wartość bufora przechwytywania pochodzącego z ?kwantyfikatora (dopasuj 1 lub 0 razy), gdy jest zagnieżdżony w innym buforze przechwytywania kwantyfikatora, jest inna

W Perlu będzie zawierało "a" i zawierało , ale w PCRE będzie zawierało "b". "aba" =~ /^(a(b)?)+$/;$1$2undef$2

PCRE umożliwia nadawanie nazwanym buforom przechwytywania nazw numerycznych; Perl wymaga, aby nazwa była zgodna z regułą gołych słów

Oznacza to, że \g{}jest to jednoznaczne w Perlu, ale potencjalnie niejednoznaczne w PCRE.

Nie jest to już różnica od wersji PCRE 8.34 (wydanej 15.12.2013), która nie pozwala już na rozpoczynanie nazw grup od cyfry.

PCRE pozwala na różne długości alternatyw w ramach lookbehind

W asercjach wstecznych zarówno PCRE, jak i Perl wymagają wzorców o stałej długości.

Oznacza to, że zarówno PCRE, jak i Perl nie zezwalają na wzorce o zmiennej długości.

Jednak Perl wymaga, aby wszystkie alternatywne gałęzie asercji wstecznej miały taką samą długość, podczas gdy PCRE pozwala tym alternatywnym gałęziom mieć różne długości, o ile każda gałąź ma stałą długość.

PCRE nie obsługuje niektórych „eksperymentalnych” konstrukcji Perla

Takie jak (??{...})(wywołanie zwrotne, którego zwrot jest oceniany jako część wzorca) ani (?{})konstrukcja, chociaż ta ostatnia może być emulowana za pomocą (?Cn).

Czasowniki kontrolne rekursji dodane w serii Perl 5.9.x również nie są obsługiwane.

Obsługa eksperymentalnych czasowników sterujących z wycofywaniem (dodanych w Perl 5.10) jest dostępna w PCRE od wersji 7.3.

Są to (*FAIL), (*F), (*PRUNE), (*SKIP), (*THEN), (*COMMIT), i (*ACCEPT).

Odpowiednie użycie argumentów Perla z czasownikami sterującymi z wycofywaniem nie jest ogólnie obsługiwane.

Należy jednak pamiętać, że od wersji 8.10, PCRE obsługuje następujące czasowniki z określonego argumentu: (*MARK:markName), (*SKIP:markName), (*PRUNE:markName), i (*THEN:markName).

Od wersji 10.32 PCRE2 wspiera (*ACCEPT:markName), (*FAIL:markName)i (*COMMIT:markName).

PCRE i Perl różnią się nieco pod względem tolerancji błędnych konstrukcji

Perl dopuszcza kwantyfikatory w (?!...)konstrukcji, która jest bez znaczenia, ale nieszkodliwa (choć nieefektywna); PCRE generuje błąd w wersjach wcześniejszych niż 8.13.

PCRE ma sztywny limit głębokości rekurencji, Perl nie

Z domyślnymi opcjami kompilacji nie uda się dopasować ze względu na limit, ale Perl dopasuje to poprawnie. "bbbbXcXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" =~ /.X(.+)+X/

Perl używa sterty do rekurencji i nie ma sztywnego limitu głębokości rekurencji, podczas gdy PCRE2 ma domyślny limit czasu kompilacji, który można dostosować w górę lub w dół przez aplikację wywołującą.

Z wyjątkiem powyższych punktów, PCRE jest w stanie przejść testy w t/op/re_testspliku Perl " ", jednym z głównych testów regresji na poziomie składni dla silnika wyrażeń regularnych Perla.

Uwagi i referencje

Uwagi

  1. ^ Podstawowa biblioteka PCRE2 zapewnia funkcje dopasowywania, dopasowywania i zastępowania.
  2. ^ Na pewnoczęść nie jest? (tj.jako U+0085  != 0x85) Zastrzeżenie : Jeśli wzorzecnie zadziałał: poeksperymentuj z ustawieniami Unicode implementacji RegEx lub spróbuj zamienić na: \x85\xC2\x85(?:\r\n?|\n|\x0B|\f|\xC2\x85)

    \xC2\x85
    • \x{0085}
    • \u0085

Bibliografia

  1. ^ Indeks /pub/pcre/: https://ftp.pcre.org/pub/pcre/
  2. ^ Exim i PCRE: Jak wolne oprogramowanie porwało moje życie (1999-12), autor: Philip Hazel , s. 7: https://www.ukuug.org/events/winter99/proc/PH.ps

    A co z PCRE?

    • Napisany latem 1997, umieszczony na stronie ftp.
    • Ludzie go znaleźli i założyli listę mailingową.
    • Nastąpiło kilka ulepszeń.
  3. ^
  4. ^ PCRE2 - Wyrażenia regularne kompatybilne z Perlem (zmienione API) (2020), przez University of Cambridge : https://pcre.org/pcre2.txt
  5. ^ Różnice między PCRE2 i Perl (2019-07-13), Philip Hazel : https://www.pcre.org/current/doc/html/pcre2compat.html
  6. ^ Cytuj dziennik zmian PCRE ( https://www.pcre.org/original/changelog.txt ): "Perl nie pozwala już na to, aby nazwy grup zaczynały się od cyfr, więc wprowadziłem tę zmianę również w PCRE."
  7. ^ Dziennik zmian dla PCRE2: https://www.pcre.org/changelog.txt

Zobacz też

Zewnętrzne linki