RegEx - What to know about

Aus Laub-Home Wiki

Reguläre Ausdrücke (englisch: regular expressions, kurz RegEx) ist eine spezielle Syntax, mit deren Hilfe in einem String bestimmte Substrings gefunden werden können. Diese Substrings werden auch als "match" (Übereinstimmung) bezeichnet. RegEx wird oft in Kombination mit den Unix-Tools grep, sed und awk eingesetzt.

Finde Zeichen für Zeichen

Die einfachste Form von RegEx ist das finden eines Zeichens

# RegEx
e

# Teststring
Letztens war ich mit meinen Kollegen auf der Alm Schifahren!
 ^   ^                ^  ^      ^ ^       ^              ^

Der RegEx findet alle Buchstaben e in dem Teststring. Es können aber auch ganze Zeichenfolgen gesucht werden:

# RegEx
ABC

# Teststring
Ich kann mein ABC auswendig!
              ^^^

Hier würde der RegEx in dem angegebenen Teststring die markierte Stelle finden ("matchen"). Es ist zu beachten, dass RegEx case sensitive ist, d.h. Groß- und Kleinschreibung ist wichtig! In dem String "Ich kann mein abc auswendig!" würde das RegEx ABC keine Übereinstimmung finden. Der gesuchte RegEx wird nur als Ganzes gefunden, d.h. er findet nur ABC, aber nicht z.B. AB oder BC, schon gar nicht AC!

In RegEx gibt es keine Wörter

In dem vorherigen Beispiel wurde ABC gefunden, welches hier ein eigenständiges Wort ist. RegEx unterscheidet jedoch nicht zwischen Wörtern, Wortteilen oder Ähnlichem.

# RegEx
Hund

# Teststring
Mein Hund heißt Sammy, er lebt in einer großen Hundehütte.
     ^^^^                                      ^^^^

In dem gezeigten Beispiel wir nach Hund gesucht. In dem ersten Teil des Satzes wird auch das Wort Hund gefunden. Im zweiten Teil wird außerdem der Hund von Hundehütte gefunden. Das liegt daran, dass für RegEx ein String nur eine Aneinanderreihung von Zeichen ist, in welcher nach der gesuchten Zeichenkette gesucht wird. Das Leerzeichen ist ein vollwertiges Zeichen, welches z.B. mit dem "a" gleichgestellt ist. Im Gegensatz dazu trennt in den geschriebenen Sprachen ein Leerzeichen meist die verschiedenen Worte voneinander, weshalb dies oft als "Nichts" angesehen wird. Daher sehen wir einen Satz nicht als eine große Zeichenkette, sondern als mehrere kleine Wörter.
Ein RegEx kann auch ein Leerzeichen enthalten:

# RegEx
Rot und Grün

# Teststring
Für mein Bild habe ich nur die Farben Rot und Grün verwendet.
                                      ^^^^^^^^^^^^

Der gesamte markierte Bereich, inklusive der Leerzeichen, ist der Match!

Metacharacters - Zeichen mit besonderer Bedeutung

Während im letzen Kaptel ganz einfach nach einem fest definierten String gesucht wurde ist es in vielen Fällen nötig, dass mehrere Suchkriterien gleichzeitig angewendet werden. Um dem gerecht zu werden gibt es innerhalb von RegEx einige Zeichen und bestimmte Syntax, welche eine besondere Bedeutung haben. Diese Zeichen werden als Metacharacters bezeichnet und sind das, was RegEx so mächtig macht. Diese lassen ein RegEx jedoch auch manchmal extrem kompliziert aussehen, was viele davon abschreckt, sich mit RegEx zu beschäftigen oder es gar zu erlernen.
Die folgenden Abschnitte beschäftigen sich mit den Metacharacteren.

Das Zirkumflex ist der Anfang...

Was ist das Zirkumflex? Dahinter verbirgt sich das oft als "Dach" bezeichnete Zeichen "^". Wenn es bei einem RegEx am Anfang steht symbolisiert es den Anfang des Strings, welcher durchsucht werden soll.

# RegEX
^Was

# Teststring
Was kann man nicht alles mit Wasser machen?
^^^

Wie zu sehen ist wird nur das "Was" am Anfang des Strings gefunden, nicht jedoch die ersten drei Buchstaben des Wortes "Wasser". Dies liegt daran, dass es nicht am Anfang des Strings steht.
Diese besondere Bedeutung des Zirkumflex gilt nur, wenn es das erste Zeichen des RegEx ist! Steht es an einer anderen Stelle, dann wird es als ganz normales Zeichen behandelt.

...ein Dollar ist das Ende

Das Dollarzeichen ist sehr einfach erklärt. Während das Zirkumflex den Anfang des Suchstrings symbolisiert, ist das Dollarzeichen "$" das Ende des Suchstrings.

# RegEx
sein$

# Teststring
sein oder nicht sein
                ^^^^

Auch hier gilt, dass Dollar nur seine besondere Bedeutung hat, wenn es das letzte Zeichen des RegEx ist. An jeder anderen Stelle ist es ein ganz normales Zeichen.

Zeichengruppen - wähle deinen Treffer

Zeichengruppen helfen dabei, nach variablen Werten zu suchen. Bei ihr wird eine beliebige Anzahl von Zeichen angegeben, bei welchen ein Match gefunden werden soll. Deklariert werden sie durch eckige Klammern, in welchen die möglichen Zeichen angegeben werden.

# Beispiel einer Zeichengruppe
[abcdef]

Jede Zeichengruppe steht für genau ein Zeichen. Bei dem Beispiel oben haben wir die ersten sechs kleinen Buchstaben des Alphabets angegeben, d.h sie repräsentiert entweder ein "a", ein "b", ein "c", ein "d", ein "e" oder ein "f". Sie steht nicht für den String "abcdef".
Eine Zeichengruppe kann z.B. dazu nützlich sein, nach einem Wort zu suchen, wobei es egal ist, ob dieses Groß oder kleingeschrieben wird.

# RegEx
[Ww]er

# Teststring
Wer sind sie und werden wir uns wiedersehen?
^^^              ^^^

In dem Beispiel wird sowohl das "Wer", als auch die ersten drei Buchstaben von "werden" gefunden, da bei dem RegEx das erste Zeichen entweder ein großes oder ein kleines "w" sein kann.
Egal wie lang eine Zeichengruppe ist, sie repräsentiert immer nur ein einziges Zeichen!
Innerhalb einer Zeichengruppe werden alle Zeichen, auch Metacharacters, als ganz normale Zeichen behandelt. Nur die Zeichen "^" und "-" haben eine besondere Bedeutung, aber dazu mehr in den nächsten Abschnitten.
Sollen die Zeichen "[" und "]" selbst Teil einer Zeichengruppe sein, so muss folgendes beachtet werden:

  • das "[" kann jeder Zeit innerhalb einer Zeichengruppe vorkommen und wird als normales Zeichen behandelt ("verschachteln" von Zeichengruppen ist nicht möglich)
  • soll "]" vorkommen, so muss es das erste Zeichen innerhalb der Zeichengruppe sein, an jeder anderen Stelle wird es als der Abschluss der Zeichengruppe betrachtet (es gibt eine Ausnahme, siehe unten)
# Zeichengruppe
[]a[gr]

Bei dem ersten "]" wird nicht wie erwartet die Zeichengruppe geschlossen (es würde sonst eine leere Zeichengruppe entstehen), sondern es wird als normales Zeichen behandelt, d.h. die Zeichengruppe repräsentiert die Zeichen "]", "a", "[", "g" und "r". Dieses Beispiel zeigt gut, wie verwirrend RegEx sein kann, da es auf den ersten Blick wie zwei Zeichengruppen aussieht, zwischen welchen ein "a" ist. Es ist allerdings nur eine.

Zeichengruppen - gib einen Bereich an

Möchte man in einer Zeichengruppe relativ viele Zeichen benutzen wird der RegEx schnell sehr lang und unübersichtlich. Daher hat man innerhalb einer Zeichengruppe die Möglichkeit, Bereiche (englisch "ranges") von Zeichen anzugeben. Diese werden mit einem "-" zwischen zwei Zeichen angegeben:

# Zeichengruppe
[0-9]

Hier repräsentiert die Zeichengruppe alle Ziffern von 0 bis 9, ohne einen Bereich aus Ziffern hätte das Ganze so ausgesehen:

# Zeichengruppe
[0123456789]

Dies geht auch mit Buchstaben:

# Zeichengruppe 1
[a-z]

# Zeichengruppe 2
[Z-A]

# Zeichengruppe 3
[5-T]

Die erste Zeichengruppe findet alle kleinen Buchstaben, von a bis z.
Die zweite Zeichengruppe findet alle großen Buchstaben von A bis Z, die Reihenfolge ist hierbei nicht wichtig. Doch was ist mit Zeichengruppe 3? Der Bereich zwischen den zwei Zeichen bezieht sich auf die ASCII-Tabelle, d.h. die Zeichengruppe 3 repräsentiert die Ziffern von 5 bis 9, A bis T, aber auch ";", ":", "<", "=", ">", "?" und "@".
Und wie kann ich das "-" mit einbeziehen? Um dies bewerkstelligen zu können muss das "-" entweder das erste oder das letzte Zeichne der Zeichengruppe sein (es gibt eine Ausnahme, siehe unten). D.h. folgende Zeichengruppen repräsentieren ein "a", eine "6" und ein "-". Sie enthält keinen Bereich von Ziffern!

# Zeichengruppe 1
[-a6]

# Zeichengruppe 2
[6a-]

Außerdem sind die beiden Zeichengruppen logisch identisch, d.h. beide führen zu dem gleichen Ergebnis.
Es können auch mehrere Bereiche innerhalb einer Zeichengruppe angegeben werden:

# Zeichengruppe
[0-9a-zA-Z]

Diese Zeichengruppe trifft auf alle Ziffern von 0 bis 9, alle kleinen Buchstaben von a bis z und alle großen Buchstaben von A bis Z zu, allerdings nicht auf Zeichen wie "<" (das wäre passiert, wenn wir [0-Z] genutzt hätten).

Schließe diese Zeichengruppe aus

Anstatt in einer Zeichengruppe alle Zeichen anzugeben, welche repräsentiert werden sollen können auch die angegeben werden, bei denen es zu keiner Übereinstimmung kommt. Dazu schreibt man als erstes Zeichen innerhalb der Zeichengruppe ein Zirkumflex:

# Zeichengruppe
[^a]

Diese Zeichengruppe repräsentiert alle Zeichen außer "a". Mit den Zirkumflex können auch Bereiche angegeben werden. Sollte direkt hinter dem Zirkumflex ein "-" folgen, so wird dies als normales Zeichen interpretiert und nicht als Teil eines Bereiches. Dies gilt übrigens auch für ein "]".

# Zeichengruppe 1
[^-a0-9]

# Zeichengruppe 2
[^-a-z]

In dem ersten Beispiel repräsentiert die Zeichengruppe alle Zeichen außer "-", "a" sowie die Ziffern 0-9, bei der zweiten alle außer "-" sowie die kleinen Buchstaben von a bis z. Besonders bei dem zweiten Beispiel kann es zu Verwirrung kommen.
Kommt das Zirkumflex in einer Zeichengruppe vor, ist allerdings nicht das erste Zeichen, dann wird es als ganz normales "^" betrachtet.

Tipp: Soll innerhalb einer negativen Zeichengruppe sowohl "-" als auch "]" als normale Zeichen vorkommen, so muss "]" hinter das Zirkumflex und "-" zwingend als letztes Zeichen kommen

# Zeichengruppe
[^]a0-4[B-T-]

Hier werden alle Zeichen repräsentiert außer "]", "a", die Ziffern von 0 bis 4, "[", die großen Buchstaben von B bis T und das "-". Besonders schön bei diesem Beispiel ist die Tatsache, dass es alles enthält, was wir über Zeichengruppen gelernt haben.

Raube Metacharactere ihre Bedeutung

Mit Hilfe der eckigen Klammern können Zeichengruppen definiert werden, doch wie findet man innerhalb eines Stings die geöffnete eckige Klammer "[", wenn diese eine Zeichengruppe beginnt? Um innerhalb von Strings auch nach den Metacharacters suchen zu können gibt es die Möglichkeit, dem Metacharacter seine besondere Bedeutung zu nehmen und es dadurch zu einem normalen Zeichen zu "degradieren". Dies wird im Englischen auch als "escaping" bezeichnet.
Um einen Metacharacter zu escapen muss direkt davor ein Backslash "\" gesetzt werden.

# RegEx
\[Name]

# Teststring
Mein Name ist [Name]
              ^^^^^^

Ohne den Backslash wäre das RegEx eine Zeichengruppe, welche nach einem "N", einem "a", einem "m" oder einem "e" sucht. Mit dem Backslash wird "[" ein normales Zeichen und es entsteht keine Zeichengruppe. Bei "]" ist kein Backslash nötig. Wird vorher keine Zeichengruppe geöffnet wird "]" automatisch als normales Zeichen ausgewertet. Noch einmal zur Erinnerung: Alle Metacharacters können mit dem Backslash escaped werden! Dies gilt auch für den Backslash selbst. Damit kann z.B. nach Datei-Pfaden im Windows-Umfeld gesucht werden.

# RegEx
C:\\Programs\\putty\.exe

# Teststring
Mein SSH-Client befindet sich unter C:\Programs\putty.exe
                                    ^^^^^^^^^^^^^^^^^^^^^

Ohne den zweiten Backslash würde das nachfolgende Zeichen escaped werden und RegEx würde nach "C:Programsputty.exe" suchen. Wird ein normales Zeichen escaped, hat dies auf dieses meistens keine Auswirkung, allerdings gibt es eine Ausnahme (siehe nächsten Abschnitt). Vor dem Punkt von "putty.exe" muss auch ein Backslash eingefügt werden, da der Punkt ebenfalls Metacharacter ist, aber dazu später mehr.

Geschweifte Klammern - so oft komme ich vor

Die geschweiften Klammern erlauben es festzulegen, wie oft ein bestimmtes Zeichen vorkommen soll. Die definition ist allerdings ein wenig fies, denn damit die geschweiften Klammern ihre besondere Bedeutung bekommen, muss direkt davor ein Backslash stehen (sowohl vor "{" als auch "}"). Von dieser Syntax gibt es drei Varianten:

  • Wird zwischen den Klammern nur eine Zahl n angegeben bedeutet dass, dass das vorhergehende Zeichen genau n Mal vorkommt.
# RegEx
a\{4\}

# Teststring
aabccbaaaaaaabbaaaa
      ^^^^     ^^^^
: 
Es werden nur genau vier aufeinander folgende "a" gefunden.
  • Steht hinter der Zahl n in der geschweiften Klammer ein Komma ",", so muss das vor den geschweiften Klammern stehende Zeichen mindestens n Mal vorkommen.
# RegEx
a\{4,\}

# Teststring
aabccbaaaaaaabbaaaa
      ^^^^^^^  ^^^^
Nun werden bei der zweiten "a"-Gruppe nicht nur die ersten vier "a" gefunden, sondern alle sieben.
  • Werden zwischen den geschweiften Klammern zwei Zahlen n und m angegeben, welche durch ein Komma "," getrennt sind, dann kommt das vor den geschweiften Klammern vorkommende Zeichen mindestens n Mal, aber maximal m Mal vor.
# RegEx
a\{3,6\}

# Teststring
aabccbaaaaaaabbaaaa
      ^^^^^^   ^^^^

Fehlt der Backslash werden die geschweiften Klammern als normale Zeichen ausgewertet. Wiese ist das so? Der Backslash escaped doch Metacharacters, oder? Normalerweise ist das auch so, allerdings ist es im Fall der geschweiften Klammer genau umgekehrt: Ohne Backslash sind sie escaped, mit sind sie Metacharacters.
Dies hat einen geschichtlichen Hintergrund, denn die geschweiften Klammern wurden erst relativ spät in dem ersten allgemeinen RegEx Standard (Teil von POSIX) eingeführt. Davor hat jeder Programmierer mehr oder weniger sein eigenes Süppchen gekocht. Um zu verhindern, dass alte Skripte mit RegEx, bei denen die geschweiften Klammern noch keine Metacharacter waren, plötzlich nicht mehr mit neuen Programmen, welche sich an den POSIX-Standard halten, funktionieren wurden die geschweiften Klammern mit diesem Kompromiss eingeführt. Es handelt sich hierbei also um eine Rückwärtskompatibilität.

Der Punkt - Ich könnte alles sein!

Beschäftigen wir uns nun mit dem Punkt ".". Dieser repräsentiert ein beliebiges Zeichen, welches allerdings zwingend vorkommen muss. Was das bedeutet folgt gleich.

# RegEx
.ange

# Teststring 1
Mit meiner zuverlässigen Zange zog ich den angeklebten Rauschebart von der Wange meines Bruders.
                         ^^^^^            ^^^^^                            ^^^^^

# Teststring 2
angenommen und quittiert

In dem Teststring wird Zange und Wange gefunden, allerdings auch das Leerzeichen, sowie die ersten vier Buchstaben des Wortes "angeklebt". Zur Erinnerung: Das Leerzeichen ist in RegEx ein normales Zeichen, gleichgestellt mit Buchstaben!
Nichts gefunden wird in dem zweiten String. Zwar ist ange gleich am Anfang zu finden, allerdings befindet sich davor kein anderes Zeichen. Und da der Punkt zwar alles sein kann, aber ein Zeichen zwingend vorkommen muss, wird keine Übereinstimmung gefunden.
Der Punkt wird aufgrund seiner Fähigkeit alles sein zu können auch als Wildcard bezeichnet.

Das Sternchen - von mir gibt es beliebig viele

Das Sternchen "*" ist sehr leicht erklärt. Wenn es vorkommt bedeutet das, dass das davor vorkommende Zeichen beliebig oft vorkommen kann. Dies kann allerdings auch bedeuten, dass es gar nicht vorkommt!

# RegEx
ab*c

# Teststring
ac abc abbbbbc acb ab a
^^ ^^^ ^^^^^^^ ^^

Die ersten drei Teile werden alle erkannt. Beim zweiten Teil wird "ac" erkannt, das "b" gehört allerdings nicht dazu. Der fünfte und sechste Teil wird nicht erkannt, da hier jeweils das "c" am Ende fehlt.
Eine mächtige Funktion des Sternchens ist es, dass es mit anderen Metacharacters zusammen angewendet werden kann. Oft wird ".*" benutz um beliebige Zeichen beliebig oft zu finden, aber auch Zeichengruppen können benutzt werden.

# RegEx
.*abc

# Teststring
sdcegvealbhekdabcfjeknlrnvanlk
^^^^^^^^^^^^^^^^^

Alle Zeichen bis "abc" werden gefunden.

# RegEx
a[abc]*

# Teststring
askjbpskdaaabjfjdjdacldaljs
^        ^^^^      ^^  ^

Dieses RegEx findet alle "a" gefolgt von beliebig vielen "a", "b" und/oder "c". Es werden auch allein stehende "a" gefunden, da "*" auch bedeuten kann, dass die Zeichengruppe 0 Mal vorkommt.
Das Sternchen könnte auch mit einem anderen Metacharacter erzeugt werden, der RegEx "a\{0,\}" und "a*" sind z.B. logisch identisch, die Sternchen-Variante ist jedoch um einiges kürzer und dadurch viel lesbarer.

Gruppieren mit der Klammer

Teile eines RegEx können auch gruppiert werden indem man diese mit normalen Klammern umschließt, allerdings liegt hier der gleiche Sonderfall wie bei geschweiften Klammern vor, d.h. damit die Gruppierung erkannt wird muss vor jeder Klammer ein Backslash stehen.

# RegEx
c\(abc\)*

# Teststring
abaccdcabcacabcabcabcabab
   ^^ ^^^^ ^^^^^^^^^^

Im Beispiel wird jedes "c" gefunden, gefolgt von beliebig vielen aufeinander folgenden "abc". Ein "ab" alleine führt zu keinem Treffer.

RegEx ist von Natur aus gierig

Was bedeutet diese Überschrift? Es heißt, dass ein RegEx, wenn es eine variable Anzahl von Zeichen enthält (z.B. wegen des Sternchens), immer den größten möglichen Treffer findet. Dies wird als greedy (englisch für gierig) bezeichnet.

# RegEx
<.*>

# Teststring
<a href="de.wikipedia.org">Deutsche Wikipedia</a>
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Auf den ersten Blick könnte man denken, dass nur der Teil in der ersten spitzen Klammer gefunden wird, allerdings merkt RegEx, dass nach "de.wikipedia.org"> noch eine weitere geschlossene spitze Klammer ist und nimmt diese als Treffer. Um dies zu verhindern kann ein kleiner Trick angewendet werden:

# RegEx
<[^>]*>

# Teststring
<a href="de.wikipedia.org">Deutsche Wikipedia</a>
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Anstatt eines Punktes wurde eine Zeichengruppe verwendet, welche die geschlossene spitze Klammer als Treffer ausschließt. Somit endet der mittlere Teil des RegEx nach den Gänsefüßchen und die darauf folgende spitze Klammer wird als Ende des Matches erkannt.

Lazy RegEx

Neben dem oben erwähnten Weg mit greedy umzugehen gibt es noch eine weitere Methode. Man sagt dem RegEx, dass es "faul" (englisch lazy) arbeiten soll. D.h. er dreht das greedy-Prinzip einfach um: Es wird der erste mögliche Treffer gefunden. Um dies zu bewerkstelligen muss hinter den Metacharacters, welche eine variable Anzahl von Zeichen angeben (z.B. das Sternchen) ein Fragezeichen "?".

# RegEx
<.*?>

# Teststring
<a href="de.wikipedia.org">Deutsche Wikipedia</a>
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Nun wird nur das erste Feld in spitzen Klammern gefunden.
ACHTUNG: Nicht alle Programme unterstützen dieses Lazy-Flag. Bei einem Test funktionierte dies weder in sed noch awk (wurde getestet auf Mac OS 10.8.2 und Rasbian Linux). Allerdings hat es unter Rasbian mit Perl 5.14 funktioniert. Ich empfehle Vorsicht beim Einsatz des Lazy-Flags und dass man, wenn möglich, Alternativen wie die negative Zeichengruppe verwendet!

Extended Regular Expression

Die bisher kennen gelernten Elemente von RegEx werden auch als Basic Regular Excpression (BRE) bezeichnet, allerdings gibt es auch noch eine kleine Erweiterung zu RegEx, welche als Extended Regular Expression (ERE) bekannt ist. Die folgenden Abschnitte sollen diese Elemente näher bringen.

Das Fragezeichen - Gibt es mich oder nicht?

Das Fragezeichen "?" innerhalb eines RegEx bedeute, dass das davor stehende Zeichen (oder Zeichengruppe, Gruppierung usw.) entweder genau ein oder kein Mal vorkommen soll

# RegEx
ab?

# Teststring
dslcasedbabbbabca
    ^    ^^  ^^ ^

Wie man sieht wird das einfache "a" gefunden, auch "ab", allerdings nicht die zwei danach folgenden "b", da das "b" nur maximal einmal vorkommen darf. Dieser Metacharacter kann auch mit RegEx in BRE nachgebildet werden, "ab?" (ERE) und "ab\{0,1\}" (BRE) sind logisch identisch. Es handelt sich hierbei also mehr um eine kosmetische Lösung zur besseren Lesbarkeit.

Das Pluszeichen - Mich gibt es mindestens ein Mal

Das Pluszeichen ist dem Sternchen sehr ähnlich. Es besagt, dass das davor stehende Zeichen beliebig oft vorkommen kann, allerdings mindestens ein Mal. Dementsprechend ist es wie ein Sternchen, bei dem die Möglichkeit 0 Mal vorzukommen entfallen ist.

# RegEx
aa+

# Teststring
abrdkxqaakdsngaaaaaaadklx
       ^^     ^^^^^^^

Das erste "a" wird nicht getroffen, da mindestens zwei "a" vorkommen müssen. Auch das Pluszeichen kann mit BRE nachgebildet werde, d.h. auch hier handelt es sich um eine kosmetische Lösung. "aa+" in ERE entspricht "aa\{1,\}" in BRE.

Vorbei ist es mit dem umgedrehten Escapen

Wie schon die beiden anderen Erweiterungen handelt es sich hierbei um eine kosmetische Lösung. Während in BRE für die geschweifte Klammer und die Gruppierungen mit normaler Klammer jeweils ein Backslash davor stehen muss um als Metacharacter erkannt zu werden, entfällt der Backslash bei ERE, wodurch dies wieder einheitlich mit den anderen Metacharacters ist. Der Backslash wird nun auch hier zum escapen verwendet. Nachteil ist, dass dadurch die Rückwärtskompatibilität verloren geht. Aus diesem Grund sollte man bei einem Skript immer angeben, wenn die ERE benutzt wird.

Die Pipe - Entweder oder

Eine "wahre" Neuerung in RegEx ist die Einführung des Pipe-Zeichens "|". Durch dieses kann eine logisch OR-Verknüpfung über das gesamte RegEx gezogen werden.

# RegEx
Papagei|Spatzen

# Teststring
Heute morgen sah ich nicht nur Spatzen auf dem Dach, sondern auch einen Papagei
                               ^^^^^^^                                  ^^^^^^^

Nicht nur die Spatzen werden gefunden, sondern auch der Papagei. Wichtig ist zu beachten, dass im Gegensatz zu den anderen Metacharacters sich die Pipe nicht auf das direkt davor stehende Zeichen bezieht, sonden auf das RegEx als Ganzes!

Übersicht über RegEx Metacharacters

Wenn man schnell nur die Bedeutung eines bestimmten Metacharacters sucht ist der ganze Text bis hierher etwas unhandlich, daher folgt nun eine kurze Zusammenfassung der gelernten Metacharacters als Referenz.

Metacharacter Beschreibung Beispiel RegEx Beispiel Treffer
^ Wenn es am Anfang des RegEx steht symbolisiert es den Anfang des String in welchem gesucht werden soll. ^Am Am Anfang komme ich...
$ Wenn es am Ende des RegEx steht symbolisiert es das Ende des Strings, welcher durchsucht werden soll. Ende$ Das ist das Ende
[...] Definiert eine Zeichengruppe. Treffer kann jedes Zeichen zwischen den Klammern sein. Alle Metacharacters außer "^" und "-" werden als normale Zeichen ausgewertet. Es können mit "-" Bereiche angegeben werden. Mit einem "^" am Anfang wird die Gruppe negiert. Soll "-" als Zeichen vorkommen muss es am Anfang oder am Ende der Zeichengruppe stehen, damit ein "]" als Zeichen ausgewertet wird und nicht die Gruppe beendet muss es als erstes Zeichen der Gruppe vorkommen (Zirkumflex am Anfang zählt bei beiden nicht) normal: [abc]
negiert: [^abc]
Bereiche: [a-z]
a
3
t
\ Sorgt dafür, dass der darauf folgende Metacharacter als normales Zeichen ausgewertet wird ("escapen") 192\.168\.111\.111 192.168.111.111
BRE: \{n,m\}
ERE: {n,m}
Davor stehendes Zeichen/Zeichengruppe/Gruppierung kommt n bis m Mal vor. Steht nur n in den Klammern, kommt es exakt n Mal vor, bei "n," kommt es mindestens n Mal bis unendlich vor. BRE: ab\{5\}
ERE: ab{5,}
BRE: ab\{5,10\}
abbbbb
abbbbbbb
abbbbbbbbbb
BRE: \(...\)
ERE: (...)
Erlaubt das Gruppieren von RegEx-Teilen. BRE: a\(abc\)
ERE: a(abc)
* Das davor stehende Zeichen/Zeichengruppe/Gruppierung kommt beliebig oft oder gar nicht vor. ab*c ac
abc
abbbbbc
. An der Stelle des Punktes trifft jedes beliebige Zeichen zu. Es muss zwingend ein Zeichen für den Punkt stehen! a.c abc
apc
? Nur in ERE: Das vorher stehende Zeichen/Zeichengruppe/Gruppierung kommt genau ein oder kein Mal vor. Hunde? Hund
Hunde
+ Nur in ERE: Das vorher stehende Zeichen/Zeichengruppe/Gruppierung kommt beliebig oft vor, aber mindestens ein Mal. ab+c abc
abbbbbbbbc
| Nur in ERE: Erlaubt eine logische OR-Verknüpfung über das gesamte RegEx blau|grün Der Himmel ist blau und nicht grün
? Achtung, wird von vielen Programmen nicht unterstützt (darunter sed und awk). Nur benutzen wenn unbedingt nötig: Wenn nach "*", "+" oder "\{...\}" ein Fragezeichen folgt ist dieser Teil nicht greedy sondern lazy <a.*?> <a href="de.wikipedia.org">Deutsche Wikipedia</a>

Ich habe außerdem im Bereich Weblinks eine Seite verlinkt, mit welcher man RegEx üben kann. Die Anwendung basiert auf HTML, d.h. sie ist platform-unabhängig und es muss nichts installiert werden. Besonders hilfreich ist die Tatsache, dass das RegEx live beim tippen ausgewertet wird und die Treffer hervorhebt und das wenn man mit der Maus über ein RegEx-Element geht dieses isoliert hervorgehoben und die Bedeutung per Hover-Text erklärt wird.

Oft genutzte Ausdrücke

  • Suchen nach IP-Adresse mit BRE (Korrektheit, dass jede Zahl < 256 ist, wird nicht überprüft):
[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}
  • Suchen nach HTML-Links:
<a[^>]*>[^<]*</a>
  • Sucht nach Strings: Zeichenketten, welche zwischen zwei doppelten Anführungszeichen stehen. Dabei wird beachtet, dass ein Backslash vor einem doppelten Ausführungszeichen dieses escaped und dadurch den String NICHT schließt (z.B. bei Java). Benötigt ERE.
"([^"]|\\")*"

Weblinks

Quellen