Welche Zeichen müssen in einem regulären Ausdruck maskiert werden?

22

Welche Zeichen in einem regulären Ausdruck müssen im Allgemeinen maskiert werden?

Beispielsweise ist Folgendes syntaktisch nicht korrekt:

echo '[]' | grep '[]'
grep: Unmatched [ or [^

Dies ist jedoch ist syntaktisch korrekt:

echo '[]' | grep '\[]'
[]

Gibt es eine Dokumentation darüber, welche Zeichen in einem regulären Ausdruck maskiert werden sollen und welche nicht?

LanceBaynes
quelle

Antworten:

12

Dies hängt von der Anwendung ab. In deinem Beispiel [muss als Argument dafür grepaber nicht angegeben werden echo.

Für die Shell (aus den POSIX-Spezifikationen ):

Das Zitieren wird verwendet, um die spezielle Bedeutung bestimmter Zeichen oder Wörter in der Shell zu entfernen. Anführungszeichen können verwendet werden, um die wörtliche Bedeutung der Sonderzeichen im nächsten Absatz beizubehalten, zu verhindern, dass reservierte Wörter als solche erkannt werden, und um die Parametererweiterung und das Ersetzen von Befehlen innerhalb der Here-Document-Verarbeitung zu verhindern (siehe Here-Document).

In der Anmeldung sind folgende Zeichen anzugeben, wenn sie sich selbst vertreten sollen:

|  &  ;  <  >  (  )  $  `  \  "  '  <space>  <tab>  <newline>

und das Folgende muss möglicherweise unter bestimmten Umständen angegeben werden. Das heißt, diese Zeichen können abhängig von den Bedingungen, die an anderer Stelle in diesem Band von IEEE Std 1003.1-2001 beschrieben sind, speziell sein:

*   ?   [   #   ˜   =   %

Die verschiedenen Anführungszeichen sind das Escape-Zeichen, einfache Anführungszeichen und doppelte Anführungszeichen. Das Hier-Dokument stellt eine andere Form des Zitierens dar; siehe hier-Dokument.

Bestimmte Programme (unter Verwendung von regulären Ausdrücken, Perl, awk) können zusätzliche Anforderungen an die Flucht haben.

Matteo
quelle
8

Jede Anwendung verfügt über einen eigenen Satz von Sonderzeichen. Das Problem, auf das Sie gestoßen sind, war grepnicht die Shell. grepWelche Zeichen in Anführungszeichen gesetzt werden müssen , erfahren Sie auf der Manpage unter "REGELMÄSSIGE AUSDRÜCKE".

Für die Shell sollten folgende Zeichen in Anführungszeichen gesetzt werden:

;'"`#$&*?[]<>{}\

und ein beliebiges Leerzeichen.

Abhängig von der Shell müssen möglicherweise auch andere Zeichen in Anführungszeichen gesetzt werden:

!^%

Schauen Sie unter "SHELL GRAMMAR" in der Manpage der Shell nach.

Arcege
quelle
In einigen Shells mit Verlaufserweiterung ( bashenthalten) !wird die Erweiterung immer noch in doppelte Anführungszeichen gesetzt. Nur einfache Anführungszeichen stoppen die Erweiterung (oder deaktivieren die Shell-Option).
Chris Down
]sollte nicht immer zitiert werden [. Ich fand keinen Hinweis auf {und}
Matteo
8

Es gibt mehrere Arten von regulären Ausdrücken, und die Anzahl der Sonderzeichen hängt vom jeweiligen Typ ab. Einige von ihnen werden im Folgenden beschrieben. In allen Fällen werden Sonderzeichen durch einen Backslash maskiert \. ZB passend [schreiben Sie \[stattdessen. Alternativ können die Zeichen (mit Ausnahme von ^) maskiert werden, indem sie nacheinander in eckige Klammern gesetzt werden [[].

Die Zeichen, die in bestimmten Kontexten ^speziell sind, z. B. am Anfang eines (Unter-) Ausdrucks, können in allen Kontexten maskiert werden.

Wie schon andere geschrieben haben: Wenn Sie in der Shell den Ausdruck nicht in einfache Anführungszeichen setzen, müssen Sie zusätzlich die Sonderzeichen für die Shell in der bereits entkoppelten Regex entkoppeln. Beispiel: Anstatt '\['Sie können \\[(alternativ: "\["oder "\\[") in Bourne-kompatiblen Shells wie Bash schreiben, aber dies ist eine andere Geschichte.

Grundlegende reguläre Ausdrücke (BRE)

  • POSIX: Grundlegende reguläre Ausdrücke
  • Befehle: grep,sed
  • Spezielle Charaktere: .[\
  • Besonderes in einigen Zusammenhängen: *^$
  • Entkomme einer Zeichenkette: "$(printf '%s' "$string" | sed 's/[.[\*^$]/\\&/g')"

Erweiterte reguläre Ausdrücke (ERE)

  • POSIX: Erweiterte reguläre Ausdrücke
  • Befehle:, grep -EGNU :, sed -r* BSD:sed -E
  • Spezielle Charaktere: .[\(
  • Besonderes in einigen Zusammenhängen: *^$)+?{|
  • Entkomme einer Zeichenkette: "$(printf '%s' "$string" | sed 's/[.[\*^$()+?{|]/\\&/g')"
Pabouk
quelle
3

grepverwendet BRE als reguläre Ausdrücke. Es gibt gute Dokumentation auf es hier , ein allgemeiner Überblick „keine Sonderzeichen oder metacharacter entkommen wörtlichen zu bekommen, entkommen Escape - Sequenzen zu erstellen (wäre \n, \rusw.)“, obwohl dies nicht immer der Fall ist, zum Beispiel, müssen Sie entkommen (und )ihre besondere Bedeutung bekommen (Rückverweis).

Chris Down
quelle
0

Die Shell kann die Befehlszeile vor der Befehlsausführung transformieren. Sowohl die Shell als auch grepkönnen Anführungszeichen verwenden, um die spezielle Bedeutung einiger Zeichen zu entfernen. Dennoch grepund Muscheln haben unterschiedliche Sonderzeichen. Darüber hinaus werden nicht maskierte Sonderzeichen, die sich nicht aus einer vorhandenen Erweiterung ergeben haben, vor der Befehlsausführung von der Shell entfernt.

echo '[]' | grep '[]'

Die Shell überträgt das Argument []an grepund es wird von als fehlerhafter Klammerausdruck analysiert grep.

echo '[]' | grep \[]

Oben sehen wir einen ähnlichen Fall. Der Backslash wird entfernt und []als Argument an übergeben grep. grepErkennt einen fehlerhaften Klammerausdruck.

echo '[]' | grep '\[]'

Schließlich werden in diesem Fall die Anführungszeichen von der Shell entfernt und \[]als Argument an übergeben grep, in diesem speziellen Fall wird ¹ \[jedoch grepals wörtliche Klammer interpretiert . Anführungszeichen sind erforderlich, um zu verhindern, dass der Backslash von der Shell als Sonderzeichen interpretiert wird.


¹ POSIX-Spezifikation .

Fólkvangr
quelle