Ich bin es leid, immer zu raten, ob ich Sonderzeichen wie ' ()[]{}|
' usw. entkommen sollte, wenn ich viele Implementierungen von regulären Ausdrücken verwende.
Dies ist beispielsweise bei Python, sed, grep, awk, Perl, Umbenennen, Apache, find usw. anders. Gibt es einen Regelsatz, der festlegt, wann ich Sonderzeichen entkommen soll und wann nicht? Kommt es auf den Regexp-Typ an, wie PCRE, POSIX oder erweiterte Regexps?
escape()
", um die Verwendung beliebiger Zeichenfolgen als Regex-Teile zu ermöglichen.Antworten:
Welche Charaktere du musst und welchen du nicht entkommen darfst, hängt von der Regex-Variante ab, mit der du arbeitest.
Vermeiden Sie für PCRE und die meisten anderen sogenannten Perl-kompatiblen Geschmacksrichtungen die folgenden externen Zeichenklassen:
und diese innerhalb der Charakterklassen:
Bei POSIX Extended Regexes (ERE) können Sie diese externen Zeichenklassen (wie bei PCRE) umgehen:
Das Escapezeichen anderer Zeichen ist bei POSIX ERE ein Fehler.
Innerhalb von Zeichenklassen ist der Backslash ein Literalzeichen in regulären POSIX-Ausdrücken. Sie können es nicht verwenden, um etwas zu entkommen. Sie müssen "clevere Platzierung" verwenden, wenn Sie Zeichencharakter-Metazeichen als Literale einfügen möchten. Setzen Sie das ^ irgendwo außer am Anfang, das] am Anfang und das - am Anfang oder am Ende der Zeichenklasse, um diesen wörtlich zu entsprechen, z.
In POSIX Basic Regular Expressions (BRE) sind dies Metazeichen, denen Sie entkommen müssen, um ihre Bedeutung zu unterdrücken:
Das Entkommen von Klammern und geschweiften Klammern in BREs gibt ihnen die besondere Bedeutung, die ihre nicht entkoppelten Versionen in EREs haben. Einige Implementierungen (z. B. GNU) geben auch anderen Zeichen eine besondere Bedeutung, wenn sie maskiert werden, z. B. \? und +. Das Escapezeichen eines anderen Zeichens als. ^ $ * () {} Ist normalerweise ein Fehler bei BREs.
Innerhalb von Zeichenklassen folgen BREs der gleichen Regel wie EREs.
Wenn Ihnen das alles den Kopf verdreht , holen Sie sich eine Kopie von RegexBuddy . Klicken Sie auf der Registerkarte Erstellen auf Token einfügen und dann auf Literal. RegexBuddy fügt nach Bedarf Escapezeichen hinzu.
quelle
/
ist kein Metazeichen in einem der von mir erwähnten Geschmacksrichtungen für reguläre Ausdrücke, daher muss die Syntax für reguläre Ausdrücke nicht maskiert werden. Wenn ein regulärer Ausdruck als Literal in einer Programmiersprache zitiert wird, dann können die Zeichenfolge oder regex Formatierungsregeln dieser Sprache benötigen/
oder"
oder'
maskiert werden, und erfordern sogar `\` doppelt maskiert werden.Moderne RegEx-Aromen (PCRE)
Enthält 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.
Die PCRE-Kompatibilität kann variieren
Irgendwo:
. ^ $ * + - ? ( ) [ ] { } \ |
Legacy RegEx Flavours (BRE / ERE)
Enthält awk, ed, egrep, emacs, GNUlib, grep, PHP (ereg), MySQL, Oracle, R, sed.
Die PCRE-Unterstützung kann in späteren Versionen oder mithilfe von Erweiterungen aktiviert werden
ERE / awk / egrep / emacs
Außerhalb einer Charakterklasse:
. ^ $ * + ? ( ) [ { } \ |
Innerhalb einer Charakterklasse:
^ - [ ]
BRE / ed / grep / sed
Außerhalb einer Zeichenklasse:
. ^ $ * [ \
Innerhalb einer Zeichenklasse:
^ - [ ]
Bei Literalen nicht entkommen:
+ ? ( ) { } |
Bei Standard-Regex-Verhalten:
\+ \? \( \) \{ \} \|
Anmerkungen
\xFF
] -
nur innerhalb einer Zeichenklasse maskiert werden, aber ich habe sie der Einfachheit halber in einer einzigen Liste gespeichert"(\")(/)(\\.)"
Vergleich/(")(\/)(\.)/
zu JavaScript).quelle
-
oder]
muss außerhalb von Charakterklassen entkommen. POSIX (BRE / ERE) hat in Zeichenklassen kein Escapezeichen. Das Regex-Aroma in Delphis RTL basiert tatsächlich auf PCRE. Python, Ruby und XML haben ihre eigenen Varianten, die PCRE näher stehen als den POSIX-Varianten.Leider gibt es wirklich keine Escape-Codes, da diese je nach verwendeter Sprache variieren.
Das Beibehalten einer Seite wie der Seite "Tools für reguläre Ausdrücke" oder dieses Cheatsheet für reguläre Ausdrücke kann jedoch einen großen Beitrag zum schnellen Herausfiltern leisten .
quelle
\<
und\>
sind Wortgrenzen, was nur in der Boost-Regex-Bibliothek (AFAIK) zutrifft. Aber anderswo heißt es<
und>
sind Metazeichen und müssen (zu\<
und\>
) entkommen , um sie buchstäblich zu finden, was in keinem Geschmack wahr istLeider wird die Bedeutung von Dingen wie (und \ (zwischen regulären Ausdrücken im Emacs-Stil und den meisten anderen Stilen vertauscht. Wenn Sie also versuchen, diesen zu entkommen, tun Sie möglicherweise das Gegenteil von dem, was Sie wollen.
Sie müssen also wirklich wissen, welchen Stil Sie zitieren möchten.
quelle
POSIX erkennt mehrere Variationen von regulären Ausdrücken - grundlegende reguläre Ausdrücke (BRE) und erweiterte reguläre Ausdrücke (ERE). Und selbst dann gibt es Macken aufgrund der historischen Implementierungen der von POSIX standardisierten Dienstprogramme.
Es gibt keine einfache Regel, wann welche Notation verwendet werden soll oder welche Notation ein bestimmter Befehl verwendet.
Lesen Sie Jeff Friedls Mastering Regular Expressions- Buch.
quelle
Wirklich nicht. Es gibt ungefähr eine halbe Million verschiedener Regex-Syntaxen. Sie scheinen auf Perl, EMACS / GNU und AT & T im Allgemeinen zurückzuführen zu sein, aber ich werde auch immer überrascht.
quelle
Manchmal ist ein einfaches Entkommen mit den von Ihnen aufgelisteten Zeichen nicht möglich. Zum Beispiel funktioniert die Verwendung eines Backslashs, um einer Klammer zu entkommen, nicht auf der linken Seite einer Substitutionszeichenfolge in sed, nämlich
Ich neige dazu, stattdessen nur eine einfache Zeichenklassendefinition zu verwenden, sodass der obige Ausdruck wird
was ich finde, funktioniert für die meisten Regexp-Implementierungen.
Übrigens sind Zeichenklassen hübsche Vanille-Regexp-Komponenten, daher funktionieren sie in den meisten Situationen, in denen Sie in Regexps maskierte Zeichen benötigen.
Bearbeiten: Nach dem Kommentar unten dachte ich nur, ich würde die Tatsache erwähnen, dass Sie auch den Unterschied zwischen Automaten mit endlichem Zustand und Automaten mit nicht endlichem Zustand berücksichtigen müssen, wenn Sie das Verhalten der Regexp-Bewertung betrachten.
Vielleicht möchten Sie sich "das glänzende Ballbuch", auch bekannt als "Effective Perl" ( bereinigter Amazon-Link ), ansehen , insbesondere das Kapitel über reguläre Ausdrücke, um ein Gefühl für den Unterschied zwischen den Bewertungsarten der Regexp-Engine zu bekommen.
Nicht die ganze Welt ist ein PCRE!
Wie auch immer, reguläre Ausdrücke sind im Vergleich zu SNOBOL so klobig ! Nun , dass war ein interessanter Programmierkurs! Zusammen mit dem auf Simula .
Ah, die Freude, Ende der 70er Jahre an der UNSW zu studieren! (-:
quelle
Für PHP "ist es immer sicher, einem nicht alphanumerischen Zeichen" \ "voranzustellen, um anzugeben, dass es für sich selbst steht." - http://php.net/manual/en/regexp.reference.escape.php .
Außer wenn es ein "oder" ist .: /
Verwenden Sie preg_quote (), um Regex-Mustervariablen (oder Teilvariablen) in PHP zu umgehen.
quelle
Um zu wissen, wann und was ohne Versuche zu entkommen ist, muss man genau die Kontextkette verstehen, die der String durchläuft. Sie geben die Zeichenfolge von der entferntesten Seite bis zu ihrem endgültigen Ziel an. Dies ist der Speicher, der vom Regexp-Parsing-Code verarbeitet wird.
Beachten Sie, wie die Zeichenfolge im Speicher verarbeitet wird: Wenn es sich um eine einfache Zeichenfolge im Code oder eine in die Befehlszeile eingegebene Zeichenfolge handeln kann, kann es sich entweder um eine interaktive Befehlszeile oder eine Befehlszeile handeln, die in einer Shell-Skriptdatei angegeben ist, oder innerhalb einer Variablen im Speicher, die vom Code erwähnt wird, oder eines (Zeichenfolgen-) Arguments durch weitere Auswertung oder einer Zeichenfolge, die Code enthält, der dynamisch mit jeder Art von Kapselung generiert wird ...
Jedem dieser Kontexte wurden einige Zeichen mit besonderen Funktionen zugewiesen.
Wenn Sie das Zeichen buchstäblich übergeben möchten, ohne seine spezielle Funktion (lokal für den Kontext) zu verwenden, müssen Sie es für den nächsten Kontext maskieren ... was möglicherweise einige andere Escape-Zeichen erfordert, die möglicherweise zusätzlich benötigt werden in den vorhergehenden Kontexten entkommen. Darüber hinaus kann es Dinge wie die Zeichenkodierung geben (die heimtückischste ist utf-8, da sie für gängige Zeichen wie ASCII aussieht, aber abhängig von ihren Einstellungen optional auch vom Terminal interpretiert werden kann, sodass sie sich möglicherweise anders verhält als das Kodierungsattribut von HTML / XML, es ist notwendig, den Prozess genau richtig zu verstehen.
Beispiel: Ein regulärer Ausdruck in der Befehlszeile, der mit beginnt
perl -npe
, muss an eine Reihe von Exec -Systemaufrufen übertragen werden, die als Pipe die Datei handhaben. Jeder dieser Exec-Systemaufrufe enthält nur eine Liste von Argumenten, die durch (nicht maskierte) Leerzeichen getrennt wurden. und möglicherweise Pipes (|) und Umleitung (> N> N> & M), Klammern, interaktive Erweiterung von*
und?
,$(())
... (all dies sind Sonderzeichen, die vom * sh verwendet werden und die das Zeichen des regulären Ausdrucks im nächsten Kontext möglicherweise stören, aber in der folgenden Reihenfolge ausgewertet werden: vor der Befehlszeile. Die Befehlszeile wird von a gelesen Programmieren Sie als bash / sh / csh / tcsh / zsh, im Wesentlichen innerhalb von doppelten oder einfachen Anführungszeichen ist das Escape einfacher, aber es ist nicht erforderlich, eine Zeichenfolge in der Befehlszeile in Anführungszeichen zu setzen, da dem Leerzeichen meistens ein Backslash vorangestellt werden muss und das Anführungszeichen stehen Es ist nicht erforderlich, die Erweiterungsfunktion für die Zeichen * und? verfügbar zu lassen, aber diese Analyse unterscheidet sich von einem anderen Kontext als im Anführungszeichen. Wenn die Befehlszeile ausgewertet wird, wird der im Speicher erhaltene reguläre Ausdruck (nicht wie in der Befehlszeile angegeben) genauso behandelt wie er wäre in einer Quelldatei. Für reguläre Ausdrücke gibt es einen Zeichensatzkontext in eckigen Klammern [],Perl regulärer Ausdruck kann durch eine große Menge nicht alfa-numerischer Zeichen zitiert werden (z. B. m // oder m: / better / for / path: ...).Sie haben weitere Details zu Zeichen in anderen Antworten, die sehr spezifisch für den endgültigen regulären Ausdruckskontext sind. Wie ich bereits erwähnt habe, erwähnen Sie, dass Sie das Regexp-Escape bei Versuchen finden. Dies liegt wahrscheinlich daran, dass in verschiedenen Kontexten unterschiedliche Zeichensätze vorhanden sind, die Ihre Erinnerung an Versuche verwirren (häufig ist Backslash das Zeichen, das in diesen unterschiedlichen Kontexten verwendet wird, um einem Literalzeichen anstelle seiner Funktion zu entkommen ).
quelle
https://perldoc.perl.org/perlre.html#Quoting-metacharacters und https://perldoc.perl.org/functions/quotemeta.html
In der offiziellen Dokumentation werden solche Zeichen als Metazeichen bezeichnet. Beispiel für ein Zitat:
quelle
Für Ionic (Typescript) müssen Sie einen doppelten Schrägstrich verwenden, um die Zeichen zu formen. Zum Beispiel (dies entspricht einigen Sonderzeichen):
Achten Sie auf diese
] [ - _ . /
Zeichen. Sie müssen doppelt aufgeschlitzt werden. Wenn Sie dies nicht tun, wird ein Tippfehler in Ihrem Code auftreten.quelle