Mam dość ciągłego zgadywania, czy powinienem unikać znaków specjalnych, takich jak „ ()[]{}|
” itp., Gdy używam wielu implementacji wyrażeń regularnych.
Różni się na przykład w Pythonie, sed, grep, awk, Perl, zmiana nazwy, Apache, find i tak dalej. Czy jest jakiś zestaw reguł, który mówi, kiedy powinienem, a kiedy nie, unikać znaków specjalnych? Czy to zależy od typu wyrażeń regularnych, takich jak PCRE, POSIX lub rozszerzone wyrażenia regularne?
escape()
”, aby umożliwić stosowanie dowolnych ciągów jako części wyrażeń regularnych.Odpowiedzi:
To, które postacie musisz, a których nie możesz uciec, zależy od smaku wyrażenia regularnego, z którym pracujesz.
W przypadku PCRE i większości innych tak zwanych smaków zgodnych z Perlem unikaj tych zewnętrznych klas postaci:
i te wewnątrz klas postaci:
W przypadku rozszerzonych wyrażeń regularnych POSIX (ERE), unikaj tych zewnętrznych klas znaków (takich samych jak PCRE):
Ucieczka jakichkolwiek innych znaków jest błędem w POSIX ERE.
Wewnątrz klas znaków odwrotny ukośnik to dosłowny znak w wyrażeniach regularnych POSIX. Nie możesz go użyć, aby cokolwiek uciec. Musisz użyć „sprytnego umiejscowienia”, jeśli chcesz uwzględnić metaznaki klasy znaków jako literały. Umieść ^ gdziekolwiek oprócz początku,] na początku i - na początku lub na końcu klasy znaków, aby dosłownie je dopasować, np .:
W POSIX-owych podstawowych wyrażeniach regularnych (BRE) są to metaznaki, które musisz uciec, aby ukryć ich znaczenie:
Unikanie nawiasów i nawiasów klamrowych w BRE daje im specjalne znaczenie, jakie mają ich nieskalowane wersje w ERE. Niektóre implementacje (np. GNU) również nadają specjalne znaczenie innym znakom podczas ucieczki, takim jak \? i +. Ucieczka od znaku innego niż. ^ $ * () {} Jest zwykle błędem w BRE.
W klasach postaci BRE mają tę samą zasadę, co ERE.
Jeśli wszystko to powoduje, że kręci Ci się w głowie, weź kopię RegexBuddy . Na karcie Utwórz kliknij opcję Wstaw token, a następnie Literał. RegexBuddy doda ucieczki w razie potrzeby.
źródło
/
nie jest metaznakiem w żadnym ze smaków wyrażeń regularnych, o których wspomniałem, więc składnia wyrażeń regularnych nie wymaga zmiany znaczenia. Gdy wyrażenie regularne jest cytowany jako dosłowny w języku programowania, a następnie ciąg lub regex formatowania reguł tego języka mogą wymagać/
lub"
czy'
należy uciec, a może nawet wymagać `\` być podwójnie uciekł.Nowoczesne smaki RegEx (PCRE)
Obejmuje C, C ++, Delphi, EditPad, Java, JavaScript, Perl, PHP (preg), PostgreSQL, PowerGREP, PowerShell, Python, REALbasic, Real Studio, Ruby, TCL, VB.Net, VBScript, wxWidgets, XML Schema, Xojo, XRegExp.
Kompatybilność z PCRE może się różnić
Gdziekolwiek:
. ^ $ * + - ? ( ) [ ] { } \ |
Starsze RegEx Flavours (BRE / ERE)
Obejmuje awk, ed, egrep, emacs, GNUlib, grep, PHP (ereg), MySQL, Oracle, R, sed.
Obsługa PCRE może być włączona w późniejszych wersjach lub przy użyciu rozszerzeń
ERE / awk / egrep / emacs
Poza klasą postaci:
. ^ $ * + ? ( ) [ { } \ |
Wewnątrz klasy postaci:
^ - [ ]
BRE / ed / grep / sed
Poza klasą znaków:
. ^ $ * [ \
Wewnątrz klasy znaków:
^ - [ ]
W przypadku literałów, nie uciekaj:
+ ? ( ) { } |
Aby uzyskać standardowe zachowanie wyrażenia regularnego, należy:
\+ \? \( \) \{ \} \|
Notatki
\xFF
] -
potrzebuję tylko ucieczki w obrębie klasy postaci, ale dla uproszczenia trzymałem je na jednej liście"(\")(/)(\\.)"
porównaniu do/(")(\/)(\.)/
w JavaScript)źródło
-
lub]
być ocalałem klas postaci zewnętrznych. POSIX (BRE / ERE) nie ma znaku ucieczki w klasach postaci. Smak regex w RTL Delphi jest oparty na PCRE. Python, Ruby i XML mają swoje własne smaki, które są bliższe PCRE niż POSIX-owi.Niestety tak naprawdę nie ma zestawu kodów ucieczki, ponieważ różni się w zależności od używanego języka.
Jednak utrzymywanie strony takiej jak Strona narzędzi do wyrażeń regularnych lub ta karta z wyrażeniami regularnymi może pomóc w szybkim odfiltrowaniu.
źródło
\<
i\>
jest granicami słów, co jest prawdą tylko (AFAIK) w bibliotece wyrażeń regularnych Boost. Ale gdzie indziej jest napisane<
i>
są metaznakami i muszą być uciekane (do\<
i\>
), aby dosłownie je dopasować, co nie jest prawdą w żadnym smakuNiestety znaczenie rzeczy takich jak (i \ (są zamieniane między wyrażeniami regularnymi w stylu Emacsa a większością innych stylów. Więc jeśli spróbujesz uciec od nich, możesz robić coś przeciwnego do tego, czego chcesz.
Więc naprawdę musisz wiedzieć, jaki styl próbujesz zacytować.
źródło
POSIX rozpoznaje wiele odmian wyrażeń regularnych - podstawowe wyrażenia regularne (BRE) i rozszerzone wyrażenia regularne (ERE). Nawet wtedy pojawiają się dziwactwa z powodu historycznych implementacji narzędzi znormalizowanych przez POSIX.
Nie ma prostej zasady określającej, kiedy użyć notacji, a nawet jakiej notacji używa dane polecenie.
Sprawdź książkę Mastering Regular Expressions Jeffa Friedla .
źródło
Naprawdę nie ma. istnieje około pół zyliona różnych składni wyrażeń regularnych; wydają się sprowadzać do Perla, EMACS / GNU i AT&T w ogóle, ale ja też zawsze jestem zaskoczony.
źródło
Czasami proste ucieczka nie jest możliwa w przypadku postaci, które wymieniłeś. Na przykład użycie ukośnika odwrotnego do nawiasu klamrowego nie będzie działać po lewej stronie łańcucha podstawienia w sed, a mianowicie
Zamiast tego używam prostej definicji klasy znaków, więc powyższe wyrażenie staje się
które znajduję działa dla większości implementacji wyrażeń regularnych.
Klasy znaków BTW są dość waniliowymi komponentami regularnymi, więc zwykle działają w większości sytuacji, w których potrzebujesz znaków ucieczkowych w wyrażeniach regularnych.
Edytować: Po komentarzu poniżej, pomyślałem, że wspomnę o tym, że musisz również wziąć pod uwagę różnicę między automatami stanu skończonego a automatami stanu nieskończonego, patrząc na zachowanie oceny wyrażenia regularnego.
Możesz zajrzeć do „książki z błyszczącą kulą”, znanej również jako Effective Perl ( zdezynfekowany link do Amazon) ), a konkretnie do rozdziału o wyrażeniach regularnych, aby poczuć różnicę w typach oceny silnika wyrażenia regularnego.
Nie cały świat jest PCRE!
Zresztą wyrażenia regularne są tak niezgrabne w porównaniu do SNOBOL ! Teraz , że był ciekawy kurs programowania! Wraz z tą na Simuli .
Ach, radość z nauki w UNSW pod koniec lat 70-tych! (-:
źródło
W przypadku PHP „zawsze można bezpiecznie poprzedzać znak niealfanumeryczny znakiem„ \ ”, aby określić, że oznacza on siebie”. - http://php.net/manual/en/regexp.reference.escape.php .
Z wyjątkiem jeśli jest to „lub”.: /
Aby uniknąć zmiennych wzorca wyrażeń regularnych (lub zmiennych częściowych) w PHP, użyj preg_quote ()
źródło
Aby dokładnie wiedzieć, kiedy i co uciec bez prób, konieczne jest dokładne zrozumienie łańcucha kontekstów, przez które przechodzi ciąg. Określisz ciąg od najdalszej strony do jego końcowego miejsca docelowego, którym jest pamięć obsługiwana przez kod parsujący wyrażenia regularnego.
Pamiętaj, jak przetwarzany jest ciąg znaków w pamięci: jeśli może to być zwykły ciąg znaków w kodzie lub ciąg znaków wprowadzony do wiersza poleceń, ale może to być interaktywny wiersz poleceń lub wiersz poleceń podany w pliku skryptu powłoki lub wewnątrz zmiennej w pamięci wymienionej w kodzie lub argumentu (ciągu znaków) w wyniku dalszej oceny lub ciągu zawierającego kod generowany dynamicznie przy użyciu dowolnego rodzaju enkapsulacji ...
Każdemu z tych kontekstów przypisano niektóre znaki o specjalnej funkcjonalności.
Jeśli chcesz przekazać znak dosłownie bez użycia jego specjalnej funkcji (lokalnej dla kontekstu), to jest to przypadek, w którym musisz go uciec, dla następnego kontekstu ... który może wymagać kilku innych znaków zmiany znaczenia, które mogą dodatkowo wymagać uciekł w poprzednich kontekstach. Ponadto mogą istnieć rzeczy takie jak kodowanie znaków (najbardziej podstępny jest utf-8, ponieważ wygląda jak ASCII dla zwykłych znaków, ale może być opcjonalnie interpretowany nawet przez terminal w zależności od jego ustawień, aby mógł zachowywać się inaczej, niż atrybut kodowania HTML / XML, konieczne jest dokładne zrozumienie procesu.
Np. Wyrażenie regularne w linii poleceń zaczynające się od
perl -npe
, musi zostać przesłane do zestawu exec wywołań systemowych łączących się jako potok obsługi plików, każde z tych wywołań systemowych exec ma tylko listę argumentów oddzielonych spacjami (bez znaków zmiany znaczenia), i ewentualnie potoki (|) i przekierowanie (> N> N> i M), nawiasy, interaktywna rozbudowa*
i?
,$(())
... (wszystkie są znakami specjalnymi używanymi przez * sh, które mogą wydawać się zakłócać charakter wyrażenia regularnego w następnym kontekście, ale są one oceniane w kolejności: przed wierszem poleceń. Wiersz poleceń jest odczytywany przez program jako bash / sh / csh / tcsh / zsh, zasadniczo wewnątrz podwójnego cudzysłowu lub pojedynczego cudzysłowu ucieczka jest prostsza, ale nie jest konieczne cytowanie ciągu w wierszu poleceń, ponieważ w większości miejsca należy poprzedzić ukośnikiem odwrotnym, a cytat to nie jest konieczne pozostawienie dostępnej funkcji rozwijania dla znaków * i?, ale parsowanie odbywa się w innym kontekście niż w cudzysłowie. Następnie, gdy linia poleceń jest oceniana, wyrażenie regularne uzyskane w pamięci (nie tak jak napisano w linii poleceń) jest traktowane tak samo jak byłby w pliku źródłowym. Dla wyrażenia regularnego istnieje kontekst zestawu znaków w nawiasach kwadratowych [],wyrażenie regularne perl może być cytowane przez duży zestaw znaków niealfanumerycznych (np. m // lub m: / better / for / path: ...).Masz inne szczegóły na temat znaków w innej odpowiedzi, które są bardzo specyficzne dla końcowego kontekstu wyrażenia regularnego. Jak już wspomniałem, wspomniałeś, że podczas prób odnajdujesz ucieczkę wyrażenia regularnego, prawdopodobnie dlatego, że inny kontekst ma inny zestaw znaków, który mylił twoją pamięć prób (często odwrotny ukośnik to znak używany w tym innym kontekście do ucieczki od literalnego znaku zamiast jego funkcji ).
źródło
https://perldoc.perl.org/perlre.html#Quoting-metacharacters i https://perldoc.perl.org/functions/quotemeta.html
W oficjalnej dokumentacji takie znaki nazywane są metaznakami. Przykład cytowania:
źródło
W przypadku Ionic (Typescript) musisz podwoić ukośnik, aby przeskalować znaki. Na przykład (w celu dopasowania niektórych znaków specjalnych):
Zwróć uwagę na te
] [ - _ . /
postacie. Muszą być podwójnie cięte. Jeśli tego nie zrobisz, w kodzie wystąpi błąd typu.źródło