Leider haben verschiedene Tools aus historischen Gründen eine leicht unterschiedliche Syntax für reguläre Ausdrücke, und einige Implementierungen weisen manchmal Erweiterungen auf, die von anderen Tools nicht unterstützt werden. Obwohl es eine Gemeinsamkeit gibt, scheint es, dass jeder Werkzeugschreiber einige unterschiedliche Entscheidungen getroffen hat.
Wenn Sie einen regulären Ausdruck haben, der in einem Tool funktioniert, müssen Sie ihn möglicherweise ändern, damit er in einem anderen Tool funktioniert. Die Hauptunterschiede zwischen gängigen Tools sind:
- ob die Operatoren
+?|(){}
einen Backslash benötigen;
- Welche Erweiterungen werden über die Grundlagen hinaus
.[]*^$
und in der Regel unterstützt?+?|()
In dieser Antwort liste ich die wichtigsten Standards auf . Weitere Informationen finden Sie in der Dokumentation der von Ihnen verwendeten Tools.
Der Vergleich von regulären Ausdrucksmodulen in Wikipedia enthält eine Tabelle mit den Funktionen, die von gängigen Implementierungen unterstützt werden.
Grundlegende reguläre Ausdrücke werden durch den POSIX-Standard codiert . Es ist die Syntax von grep
, sed
und vi
. Diese Syntax bietet die folgenden Funktionen:
^
und $
stimmen nur am Anfang und Ende einer Zeile überein.
.
Entspricht einem beliebigen Zeichen (oder einem beliebigen Zeichen außer einem Zeilenumbruch).
[…]
Entspricht einem beliebigen Zeichen in Klammern (Zeichensatz). Wenn das erste Zeichen nach der öffnenden Klammer ein ist ^
, werden stattdessen die nicht aufgelisteten Zeichen abgeglichen. Um ein einzuschließen ]
, setzen Sie es sofort nach dem Öffnen [
(oder danach, [^
wenn es eine negative Menge ist). Wenn -
zwischen zwei Zeichen liegt, gibt dies einen Bereich an. Um ein Literal einzuschließen -
, setzen Sie es an die Stelle, an der es nicht als Bereich analysiert werden kann.
- Backslash vor einem der
^$.*\[
Anführungszeichen des nächsten Zeichens.
*
entspricht dem vorhergehenden Zeichen oder Unterausdruck 0, 1 oder mehrmals.
\(…\)
ist eine syntaktische Gruppe zur Verwendung mit dem *
Operator oder für Rückverweise und \DIGIT
Ersetzungen.
- Rückreferenzierungen
\1
, \2
... den genauen Text der entsprechenden Gruppe, zB angepasst entsprechen \(fo*\)\(ba*\)\1
Matches foobaafoo
aber nicht foobaafo
. Es gibt keine Standardmethode, um auf die 10. Gruppe und darüber hinaus zu verweisen (die Standardbedeutung von \10
ist die erste Gruppe, gefolgt von a 0
).
Die folgenden Funktionen sind ebenfalls Standard, fehlen jedoch bei einigen eingeschränkten Implementierungen:
\{m,n\}
stimmt mit dem vorhergehenden Zeichen oder Unterausdruck zwischen m und n überein ; n oder m können weggelassen werden und bedeuten genau m .\{m\}
- In Klammern können Zeichenklassen verwendet werden, die beispielsweise
[[:alpha:]]
mit einem beliebigen Buchstaben übereinstimmen. Moderne Implementierungen von Klammerausdrücken umfassen auch Sortierelemente wie [.ll.]
und Äquivalenzklassen wie [=a=]
.
Die folgenden Erweiterungen kommen häufig vor (insbesondere in GNU-Tools), sind jedoch nicht in allen Implementierungen enthalten. Überprüfen Sie das Handbuch des verwendeten Tools.
\|
zur Abwechslung: foo\|bar
Streichhölzer foo
oder bar
.
\?
(kurz für \{0,1\}
) und \+
(kurz für \{1,\}
) stimmen höchstens 1 Mal bzw. mindestens 1 Mal mit dem vorhergehenden Zeichen oder Unterausdruck überein.
\n
Entspricht einem Zeilenumbruch, \t
einem Tab usw.
\w
Stimmt mit jedem Wortbestandteil überein (kurz, [_[:alnum:]]
aber mit Variation, wenn es um Lokalisierung geht) und \W
stimmt mit jedem Zeichen überein, das kein Wortbestandteil ist.
\<
und \>
die leere Zeichenkette nur am Anfang bzw. Ende eines Wortes suchen; \b
passt auch und \B
passt wo \b
nicht.
Beachten Sie, dass Werkzeuge ohne \|
Operator nicht die volle Kraft regulärer Ausdrücke haben. Rückverweise ermöglichen einige zusätzliche Dinge, die mit regulären Ausdrücken im mathematischen Sinne nicht möglich sind.
Erweiterte reguläre Ausdrücke werden durch den POSIX-Standard codiert . Ihr Hauptvorteil gegenüber BRE ist die Regelmäßigkeit: Alle Standardoperatoren sind bloße Interpunktionszeichen, ein Backslash, bevor ein Interpunktionszeichen ihn immer in Anführungszeichen setzt. Es ist die Syntax von awk
, grep -E
oder egrep
, GNU sed -r
, und bash=~
- Operator. Diese Syntax bietet die folgenden Funktionen:
^
und $
stimmen nur am Anfang und Ende einer Zeile überein.
.
Entspricht einem beliebigen Zeichen (oder einem beliebigen Zeichen außer einem Zeilenumbruch).
[…]
Entspricht einem beliebigen Zeichen in Klammern (Zeichensatz). Die Ergänzung mit einem Anfangsbuchstaben ^
und Bereichen funktioniert wie in BRE (siehe oben). Zeichenklassen können verwendet werden, fehlen aber in einigen Implementierungen. Moderne Implementierungen unterstützen auch Äquivalenzklassen und Sortierelemente. Ein Backslash in eckigen Klammern zitiert das nächste Zeichen in einigen, aber nicht allen Implementierungen. Damit ist \\
ein Backslash für die Portabilität gemeint.
(…)
ist eine syntaktische Gruppe zur Verwendung mit *
oder als \DIGIT
Ersatz.
|
zur Abwechslung: foo|bar
Streichhölzer foo
oder bar
.
*
, +
und ?
stimmt mehrmals mit dem vorhergehenden Zeichen oder Unterausdruck überein: 0 oder mehr für *
, 1 oder mehr für +
, 0 oder 1 für ?
.
- Backslash zitiert das nächste Zeichen, wenn es nicht alphanumerisch ist.
{m,n}
stimmt mit dem vorhergehenden Zeichen oder Unterausdruck zwischen m und n überein (fehlt in einigen Implementierungen); n oder m können weggelassen werden und bedeuten genau m .{m}
- Einige gebräuchliche Erweiterungen wie in BRE: Rückverweise (insbesondere in awk nicht vorhanden, außer in der busybox-Implementierung, in der Sie sie verwenden können ); Sonderzeichen , etc .; Wortgrenzen und Wortbestandteile und …
\DIGIT
$0 ~ "(...)\\1"
\n
\t
\b
\B
\b
\B
PCRE (Perl-kompatible reguläre Ausdrücke)
PCRE sind Erweiterungen von ERE, die ursprünglich von Perl eingeführt und von GNU grep -P
und vielen modernen Tools und Programmiersprachen übernommen wurden , normalerweise über die PCRE- Bibliothek. In der Perl-Dokumentation finden Sie eine schöne Formatierung mit Beispielen. Nicht alle Funktionen der neuesten Version von Perl werden von PCRE unterstützt (z. B. wird die Ausführung von Perl-Code nur in Perl unterstützt). Eine Zusammenfassung der unterstützten Funktionen finden Sie im PCRE-Handbuch . Die wichtigsten Ergänzungen zu ERE sind:
(?:…)
ist eine nicht erfassende Gruppe: wie (…)
, zählt aber nicht für Rückverweise.
(?=FOO)BAR
(Lookahead-) Übereinstimmungen BAR
, aber nur, wenn es auch eine Übereinstimmung gibt, um FOO
an derselben Position zu beginnen. Dies ist am nützlichsten, um eine Übereinstimmung zu verankern, ohne den folgenden Text in die Übereinstimmung einzubeziehen: foo(?=bar)
Übereinstimmungen, foo
jedoch nur, wenn darauf gefolgt wird bar
.
(?!FOO)BAR
(negativer Lookahead) passt BAR
, aber es gibt nicht auch eine Übereinstimmung für FOO
dieselbe Position. Zum Beispiel (?!foo)[a-z]+
stimmt mit jedem Wort in Kleinbuchstaben überein, das nicht mit "" beginnt foo
. [a-z]+(?![0-9)
Stimmt mit jedem Wort in Kleinbuchstaben überein, auf das keine Ziffer folgt ( foo123
es stimmt also überein, fo
aber nicht foo
).
(?<=FOO)BAR
(Lookbehind-) Übereinstimmungen BAR
, aber nur, wenn unmittelbar davor eine Übereinstimmung für steht FOO
. FOO
muss eine bekannte Länge haben (Sie können keine Wiederholungsoperatoren wie verwenden *
). Dies ist am nützlichsten, um eine Übereinstimmung zu verankern, ohne den vorhergehenden Text in die Übereinstimmung einzubeziehen: (?<=^| )foo
Übereinstimmungen, foo
jedoch nur, wenn ein Leerzeichen oder der Anfang der Zeichenfolge vorangestellt ist.
(?<!FOO)BAR
(negative lookbehind) -Matches BAR
, aber nur, wenn kein Match für unmittelbar davor steht FOO
. FOO
muss eine bekannte Länge haben (Sie können keine Wiederholungsoperatoren wie verwenden *
). Dies ist am nützlichsten, um eine Übereinstimmung zu verankern, ohne den vorhergehenden Text in die Übereinstimmung einzuschließen: (?<![a-z])foo
Übereinstimmungen, foo
jedoch nur, wenn kein Kleinbuchstabe vorangestellt ist.
Emacs
Die Syntax von Emacs liegt zwischen BRE und ERE. Zusätzlich zu Emacs ist dies die Standardsyntax für -regex
GNU find. Emacs bietet die folgenden Operatoren an:
^
, $
, .
, […]
, *
, +
, ?
Wie in ERE
\(…\)
, \|
, \{…\}
, Wie in BRE\DIGIT
- mehr Backslash-Letter-Sequenzen ;
\<
und \>
für Wortgrenzen; und mehr in neueren Versionen von Emacs, die in anderen Engines mit einer Emacs-ähnlichen Syntax häufig nicht unterstützt werden.
Shell-Globs (Platzhalter) führen einen Musterabgleich mit einer Syntax durch, die sich von regulären Ausdrücken völlig unterscheidet und weniger leistungsfähig ist. Neben Shells sind diese Platzhalter auch mit anderen Tools wie find -name
und Rsync-Filtern verfügbar . POSIX-Muster umfassen die folgenden Funktionen:
?
Stimmt mit jedem einzelnen Zeichen überein.
[…]
ist ein Zeichensatz wie in üblichen regulären Ausdruckssyntaxen. Einige Shells unterstützen keine Zeichenklassen. Einige Schalen benötigen !
statt ^
den Satz zu negieren.
*
Stimmt mit einer beliebigen Zeichenfolge überein (häufig, außer /
wenn Dateipfade übereinstimmen; wenn von /
ausgeschlossen *
, **
schließt dies manchmal ein /
, aber überprüfen Sie die Dokumentation des Tools).
- Backslash zitiert das nächste Zeichen.
Ksh bietet zusätzliche Funktionen, die dem Pattern Matching die volle Kraft regulärer Ausdrücke verleihen. Diese Funktionen sind auch in bash nach dem Ausführen verfügbar shopt -s extglob
. Zsh hat eine andere Syntax , kann aber auch die Syntax von ksh unterstützen setopt ksh_glob
.
vim
‚s und AT & T libast (wie inksh93
) one.grep
,tw
,expr
...). Mit Ausnahmeksh
ist , dass Toolset selten obwohl außerhalb von AT & T gefunden.regex(7)
stimmt jedoch mit Ihnen überein und nennt[these]
"Klammerausdrücke" und (innerhalb von "Klammerausdrücken")[:these:]
"Zeichenklassen". Ich bin mir nicht sicher, wie ich das am besten angehen soll.-
einen Bereich angibt und entweder zuerst (nach dem optionalen^
) oder zuletzt maskiert werden sollte , wenn dies wörtlich genommen werden soll. (Ich habe viele Fehler gesehen, die z.[A-z]
B. auf die Änderung in Groß- / Kleinschreibung zurückzuführen sind. Diese stimmen mit den Zeichen der Codes 65 bis 122 überein und enthalten aus Versehen jeweils Folgendes:.[\]^_`
Ich habe auch gesehen, dass die Gültigkeit[!-~]
aller druckbaren Zeichen in ANSI noch verwirrend ist , die ich lieber zu sehen , wie[\x21-\x7e]
, die zumindest einfach in ihrer Wirkung jedoch verwirrend in einer anderen Dimension ist).