462 Stimmen

Welche Sonderzeichen müssen in regulären Ausdrücken escaped werden?

Ich bin es leid, immer zu raten, ob ich Sonderzeichen wie ' ()[]{}| ' usw., wenn viele Implementierungen von Regexps verwendet werden.

Anders verhält es sich zum Beispiel mit Python, sed, grep, awk, Perl, rename, Apache, find und so weiter. Gibt es eine Regel, die mir sagt, wann ich Sonderzeichen auslassen sollte und wann nicht? Hängt das vom Regexp-Typ ab, wie PCRE, POSIX oder erweiterte Regexps?

5 Stimmen

Gute Regex-Bibliotheken haben Funktionen wie " escape() ", um die Verwendung beliebiger Zeichenketten als Regex-Teile zu ermöglichen.

2 Stimmen

Sie können Online-Regex-Ausdrucksprüfungen verwenden wie gskinner.com/RegExr (es ist kostenlos). (Tippen Sie ein und fahren Sie dann mit der Maus über die eingegebene Regex)

0 Stimmen

In PHP können Sie verwenden php.net/preg_quote

4voto

Charlie Martin Punkte 106684

Es gibt ungefähr eine halbe Million verschiedener Regex-Syntaxen; sie scheinen sich auf Perl, EMACS/GNU und AT&T im Allgemeinen zu beschränken, aber auch ich werde immer wieder überrascht.

4voto

Rob Wells Punkte 35303

Manchmal ist ein einfaches Escaping mit den von Ihnen aufgeführten Zeichen nicht möglich. Zum Beispiel funktioniert die Verwendung eines Backslashs, um eine Klammer zu umgehen, nicht auf der linken Seite einer Ersetzungszeichenfolge in sed, nämlich

sed -e 's/foo\(bar/something_else/'

Ich neige dazu, stattdessen eine einfache Zeichenklassendefinition zu verwenden, so dass der obige Ausdruck zu

sed -e 's/foo[(]bar/something_else/'

was meiner Meinung nach bei den meisten Regexp-Implementierungen funktioniert.

BTW Character Klassen sind ziemlich vanilla regexp Komponenten, so dass sie in der Regel in den meisten Situationen, in denen Sie escaped Zeichen in regexps benötigen zu arbeiten.

Bearbeiten: Nach dem unten stehenden Kommentar wollte ich nur noch erwähnen, dass man auch den Unterschied zwischen endlichen und nicht-endlichen Automaten berücksichtigen muss, wenn man das Verhalten der Regexp-Auswertung betrachtet.

Vielleicht möchten Sie einen Blick auf "the shiny ball book" alias Effective Perl ( gereinigter Amazon-Link ), insbesondere das Kapitel über reguläre Ausdrücke, um ein Gefühl für die Unterschiede zwischen den Auswertungstypen der Regexp-Engines zu bekommen.

Nicht die ganze Welt ist ein PCRE!

Wie auch immer, regexp's sind so klobig im Vergleich zu SNOBOL ! Jetzt dass war ein interessanter Programmierkurs! Zusammen mit dem Kurs über Simula .

Ah, die Freuden des Studiums an der UNSW in den späten 70er Jahren! (-:

4voto

MUY Belgium Punkte 2162

https://perldoc.perl.org/perlre.html#Quoting-metacharacters y https://perldoc.perl.org/functions/quotemeta.html

In der offiziellen Dokumentation werden solche Zeichen als Meta-Zeichen bezeichnet. Beispiel für die Zitierung:

my $regex = quotemeta($string)
s/$regex/something/

2voto

zylstra Punkte 691

Für PHP "ist es immer sicher, einem nicht-alphanumerischen Zeichen ein "\" voranzustellen, um anzugeben, dass es für sich selbst steht." - http://php.net/manual/en/regexp.reference.escape.php .

Es sei denn, es handelt sich um ein " oder '. :/

Um Regex-Mustervariablen (oder Teilvariablen) in PHP zu entschlüsseln, verwenden Sie preg_quote()

2voto

Marco Munari Punkte 122

Um zu wissen, wann und was zu entkommen, ohne Versuche ist notwendig, um genau die Kette von Kontexten die Zeichenfolge durchlaufen zu verstehen. Sie werden die Zeichenkette von der am weitesten entfernten Seite bis zu ihrem endgültigen Ziel spezifizieren, das der vom Regexp-Parsing-Code bearbeitete Speicher ist.

Achten Sie darauf, wie die Zeichenkette im Speicher verarbeitet wird: if kann eine einfache Zeichenkette innerhalb des Codes sein, oder eine Zeichenkette, die in die Befehlszeile eingegeben wird, aber a könnte entweder eine interaktive Befehlszeile oder eine Befehlszeile sein, die in einer Shell-Skriptdatei angegeben ist, oder eine Variable im Speicher, die vom Code erwähnt wird, oder ein (String)Argument durch weitere Auswertung, oder eine Zeichenkette, die Code enthält, der dynamisch mit irgendeiner Art von Kapselung erzeugt wurde...

Jedem dieser Kontexte sind einige Zeichen mit besonderen Funktionen zugeordnet.

Wenn Sie das Zeichen buchstäblich übergeben wollen, ohne seine spezielle Funktion (lokal im Kontext) zu verwenden, dann müssen Sie es für den nächsten Kontext escapen... was einige andere Escape-Zeichen benötigen könnte, die zusätzlich in den vorhergehenden Kontexten escaped werden müssen. Darüber hinaus kann es Dinge wie die Zeichenkodierung geben (das heimtückischste ist utf-8, weil es für gewöhnliche Zeichen wie ASCII aussieht, aber je nach Einstellung sogar vom Terminal interpretiert werden kann, so dass es sich anders verhält, als das Encoding-Attribut von HTML/XML, es ist notwendig, den Prozess genau zu verstehen.

Z.B. Eine Regexp in der Befehlszeile, die mit perl -npe muss auf eine Reihe von Daten übertragen werden. Ausführung Systemaufrufe, die als Pipe die Datei-Handles verbinden, jeder dieser exec-Systemaufrufe hat nur eine Liste von Argumenten, die durch (nicht escapete) Leerzeichen getrennt wurden, und möglicherweise Pipes (|) und Umleitung (> N> N>&M), Klammern, interaktive Expansion von * y ? , $(()) ... (all dies sind Sonderzeichen, die von der *sh verwendet werden und die mit dem Zeichen des regulären Ausdrucks im nächsten Kontext zu interferieren scheinen, aber sie werden in der Reihenfolge ausgewertet: vor der Befehlszeile. Die Kommandozeile wird von einem Programm wie bash/sh/csh/tcsh/zsh gelesen, im Wesentlichen ist innerhalb von doppelten Anführungszeichen oder einfachen Anführungszeichen das Escape einfacher, aber es ist nicht notwendig, eine Zeichenkette in der Kommandozeile in Anführungszeichen zu setzen, da meistens das Leerzeichen mit einem Backslash vorangestellt werden muss und die Anführungszeichen nicht notwendig sind, wobei die Expand-Funktionalität für die Zeichen * und ? verfügbar bleibt, aber diese werden in einem anderen Kontext als innerhalb von Anführungszeichen analysiert. Wenn dann die Befehlszeile ausgewertet wird, wird die Regexp im Speicher (nicht wie in der Befehlszeile geschrieben) genauso behandelt wie in einer Quelldatei. Für regexp gibt es Zeichensatzkontext innerhalb eckiger Klammern [ ], perl reguläre Ausdrücke können durch eine große Menge von nicht alphanumerischen Zeichen zitiert werden (z.B. m// oder m:/better/for/path: ...).

Sie haben mehr Details über Zeichen in anderen Antwort, die sehr spezifisch für die endgültige regexp Kontext sind. Wie ich festgestellt, dass Sie erwähnen, dass Sie die regexp Flucht mit Versuchen zu finden, das ist wahrscheinlich, weil verschiedene Kontext hat unterschiedliche Satz von Zeichen, die Ihr Gedächtnis von Versuchen verwirrt (oft Backslash ist das Zeichen in diesen verschiedenen Kontext verwendet, um ein wörtliches Zeichen statt seiner Funktion zu entkommen).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X