Reguläre Ausdrücke ein allgemeines Tutorial mit einigen Grundlagen und Beispielen für den Start
- Beschreibung
Reguläre Ausdrücke ein allgemeines Tutorial mit einigen Grundlagen für den Start
Reguläre Ausdrücke werden in sehr vielen Programmiersprachen verwendet, selbst einige Konsolenbefehle lassen die Verwendung von Regulären Ausdrücken zu.
Ich möchte hier nicht auf die Verwendung in bestimmten Programmiersprachen eingehen, sondern vielmehr auf den allgemeinen Umgang und die Grundlagen von Regulären Ausdrücken.
Zum Testen von verschiedenen Ausrücken verwende ich hier den Regex Coach den es hier zum Download gibt:
http://www.weitz.de/regex-coach/
Reguläre Ausdrücke Reguläre Ausdrücke sind bestimmte Muster (patterns) die auf eine bestimmte Zeichenkette angewendet werden um genau dieses Muster wieder in der Zeichenkette zu finden.
Und die einfache Übersetzung: Wir suchen in einem Text nach einem bestimmten Muster oder Wort, dabei bestimmen wir selbst ob wir nur das erste vorkommen des Wortes suchen oder das letzte oder alle.
Natürlich können Reguläre Ausdrücke bedeutend mehr und der Komplexität von Suchmustern sind fast keine Grenzen gesetzt, aber es geht hier nur um die Grundlagen die einem den Einstieg etwas erleichtern sollen.
Wir beginnen mit einer kleinen Demonstration und bauen diese dann schritt für schritt aus.
Ich Tippe folgendes in den Regex Coach unter Target String:
Fischers Fritze "fischt" frische Fische.
Frische Fische FISCHT Fischers "Fritze".
Suchen werden wir jetzt nach dem Wort fischt mit folgendem Regex:
Im Bild oben sieht man das ich bereits die Modifieri und g Ausgewählt habe.
Globale Modifier: werden am ende eines Regulären Ausdrucks definiert
i Es wird nicht zwischen groß und Kleinschreibung unterschieden.
g Durchsucht die ganze Zeichenfolge.
s Jede Zeile der Zeichenfolge wird einzeln behandelt.
m Die Zeichenfolge wird als ganze bahandelt.
x Lange Ausdrücke lassen sich auf mehrere Zeilen verteilen und mit einem # Dokumentieren z.B.
[a-zA-Z0-9-] # Beschreibung zum ersten Teil
U Gier unterdrücken.
Als nächstes suchen wir alle Wörter die sich innerhalb der Anführungszeichen " befinden:
Mit diesem Regex kommen wir der Sache schon recht nahe, doch Vorsicht der leider im RegexCoach fehlende Modifier U würde bei mehreren Fundstellen in einer Zeile unerwartet reagieren. Und zudem haben wir ja jetzt immer noch den Text mit den Anführungszeichen und nicht den Text innerhalb.
Also besser so:
oder doch besser so:
Und was macht der obere Regex ? Wir unterteilen den Regulären Ausdruck zur besseren Veranschaulichung.
Teil 1:
\b(?<=") Wir suchen nach dem Anführungszeichen, das Anführungszeichen gehört aber nicht zu dem Teil der auch ausgegeben werden soll,
sondern der danach folgende Text.
Wir markieren also diesen Teilbereich mit den Klammern und verwenden das erweiterte Pattern ?<= um mitzuteilen das wir alles suchen was nach dem " Zeichen kommt.
Mit dem allgemeinen Ausdruck \b teilen wir mit dass es sich an der stelle um eine Wortgrenze handeln muss, ein Übergang von einem Wortzeichen zu einem nicht Wortzeichen. Der Ausdruck \B würde die Bedeutung umkehren versuchen Sie es.
Teil 2:
.*? Es wird eine beliebige Zeichenfolge aus beliebig vielen Zeichen definiert. Das Metazeichen . (Punkt) steht für jedes beliebige Zeichen, der Quantifier * (Stern) steht für eine Anzahl von 0 oder mehr (in diesem Fall 0 oder mehr beliebige Zeichen). Das Fragezeichen ? gibt an das ein Zeichen vorkommen kann oder auch nicht.
Teil 3:
(?=")\b Betrifft alles das mit dem " Anführungszeichen endet aber ohne dieses selbst zu markieren.
Mit dem allgemeinen Ausdruck \b teilen wir mit dass es sich an der stelle um eine Wortgrenze handeln muss.
Metacharaktere
. Der Punkt steht für jedes beliebige Zeichen außer einem Zeilenumbruch, es sei denn dieser wurde mit \m angegeben.
z.B.
AB.D ist wahr bei ABCD oder ABDD oder AB7D nicht bei ABCCD. Für ABCCD wäre AB..D wieder wahr.
^ Der Zirkumflex steht für den Anfang der Zeichenkette.
z.B.
^Z trifft auf jede Zeichenkette zu die mit Z beginnt.
$ Das Dollarzeichen ist das Gegenteil zum Zirkumflex es markiert das Ende einer Zeichenkette.
z.B.
$h frifft auf alle Zeilen zu die mit einem h enden.
| Die Pipe ermöglicht es alternativen anzugeben.
z.B.
A|B findet alle A oder B Zeichen. ^(A|B) Zeichenketten die mit A oder B beginnen.
( ) Mit Runden Klammern lassen sich Bereiche in Unterausdrücke zusammenfassen.
z.B.
(A|B)(R|E) trifft auf AR, AE, BR, BE zu nicht aber auf AB oder RE oder AW.
(A(B|C|D)op) trifft auf ADop, ABop oder ACop zu nicht aber auf AOop
[ ] Die eckigen Klammern erlauben es bestimmte Zeichenklassen einzugeben.
z.B.
[abc] trifft zu auf a oder b oder c nicht auf z.
B[ae]ier trifft zu auf Baier und Beier nicht aber auf Baeier.
Um ganze Bereiche in Zeichenklassen zu definieren können wir auch folgendes verwenden:
[A-Z] trifft auf alle Zeichen von A bis Z zu.
[a-z] trifft auf alle Zeichen von a bis z zu.
[A-Za-z] trifft auf alle Zeichen von a bis z zu.
[0-9] trifft auf alle Ziffern zu.
[t-z] trifft auf alle Zeichen von t bis z zu.
Negieren können wir mit dem Zirkumflex das innerhalb einer eckigen Klammer die Funktion Negieren hat.
z.B.
[^0-9] trifft auf alle Zeichen außer Ziffern zu.
[^a-z] trifft auf alles außer Kleinbuchstaben zu.
ABCD[^E] trifft zu auf ABCDR oder ABCDT aber nicht ABCDE.
Quantifier
* Der Stern steht für beliebig viele oder gar keines.
z.B.
.* trifft auf jede beliebige Zeichenkette zu.
ABC[D]*E trifft zu auf ABCE, ABCDE, ABCDDDDDDDDE aber nicht auf ABCZE
+ Das Plus steht für eine Anzahl von 1 oder mehr.
z.B.
.+ trifft auf jede beliebige Zeichenkette zu.
ABC[D]*E trifft zu auf ABCDE, ABCDDDDDDDDE aber nicht auf ABCE oder ABCGE
? Das Fragezeichen steht für eine Anzahl von 0 oder 1. Der Bereich kann also da sein, muss aber nicht.
z.B.
ABC[D]? trifft zu auf ABC, ABCD, ABCR, ABCT aber nicht AACD
{ } Die geschweiften Klammern dienen zur numerischen Angabe einer Größenbeschränkung.
z.B.
{5} Gibt an dass genau 5 Zeichen gefunden werden müssen
a{5} trifft auf aaaaa zu aber nicht auf aaa.
ABC[D]{2} trifft auf ABCDD zu aber nicht ABCD
{2,} Gibt an dass mindestens 2 Zeichen gefunden werden müssen.
a{2,} trifft zu auf aa aber nicht a.
{3,5} Gibt an dass mindestens 3 aber höchstens 5 Zeichen gefunden werden dürfen.
AB[C]{3,5} trifft zu bei ABCCC oder ABCCCCC aber nicht bei ABCC
Der Backslash
Der Backslash ist übrigens auch ein sehr wichtiges Zeichen wenn es darum geht aus einem Metazeichen ein „normales“ Zeichen zu machen. Ein Metazeichen wir durch den Backslash maskiert.
Möchte man z.B. den * nicht in seiner Funktion als Metazeichen verwenden, sondern einfach als Stern, müssen wir ihn mit dem Backslash maskieren \*.
z.B.
\*\. trifft zu auf *.
Vordefinierte Zeichenklassen
Vordefinierte Zeichenklassen beginnen mit einem Backslash. Es handelt sich dabei um die Kurzform von verschiedenen Zeichenklassen.
\d Beschreibt eine Ziffer gleich wie [0-9].
\D Beschreibt ein Zeichen das keine Ziffer ist, also auch [^0-9] oder [^\d].
\w Beschreibt ein Buchstabe, Ziffer oder Unterstrich, ist gleichwertig mit [A-Za-z_0-9].
\W Ist die Negation zu \w also alles was kein Buchstabe, Ziffer oder Unterstrich ist. Gleichwertig mit [^\w].
\s Whitespace (Leerzeichen).
\S Alles auser Whitespace.
\b Wortgrenze, ein übergang von einem Wortzeichen in ein nicht Wortzeichen
Assertions
Mit Assertions bestimmen wir dass vor (lookbehind assertion) oder nach (lookahead assertion) einem Ausdruck ein bestimmtes Muster zu finden sein muss.
Positive Lookbehind-Assertions (?<=XXX)YYY Das Muster XXX kommt vor dem Muster YYY
z.B.
(?<=")AAA trifft zu auf BBB"AAA oder sdf"AAA aber nicht auf BBBAAA oder BB"BAAA oder B"AA
Negative Lookbehind-Assertions (?<!XXX)YYY Das Muster XXX kommt nicht vor dem Muster YYY
z.B.
(?<!")AAA trifft zu auf BBBAAA oder s"dfAAA aber nicht auf BBB"AAA
Positive Lookahead-Assertions YYY(?=XXX) Das Muster XXX kommt nach dem Muster YYY
z.B.
AAA(?=") trifft zu auf AAA" aber nicht auf AA" oder AAA
Negative Lookahead-Assertions YYY(?!XXX) Das Muster XXX kommt nicht nach dem Muster YYY
z.B.
AAA(?!") trifft zu auf AAAB oder AAAA"B aber nicht AAA"
Backreferences
Mit Backreferences kann man auf mit Klammern definierte Unterausdrücke zugreifen. Zur Auswahl des Unterausdrucks geben wir einfach jeder Klammer von links nach rechts eine Nummer.
Mit dieser Nummer wählen wir den zu verwendenden Ausdruck.
z.B. Wir suchen jede Zeichenkette die mit einem aaa oder bbb beginnt, ein darauf folgendes c , beliebige Zeichen und den Unterausdruck der ersten Klammer also 1.
(aaa|bbb)(c).*\1 trifft zu auf aaacttaaa und auf bbbcwwwwwbbb aber nicht auf aaacebbb oder aaacbbb
z.B. Wir suchen jede Zeichenkette die mit einem aaa oder bbb beginnt, ein darauf folgendes c , beliebige Zeichen und den Unterausdruck der zweiten Klammer also 2.
(aaa|bbb)(c).*\2 trifft zu auf aaactttttttttc oder bbbcc aber nicht auf aaacaaa oder bbbcaaa
Beispiele
Span oder Div Tag mit Backreference ermitteln, gefunden werden nur <span ......> Tags die auch mit einem </span> enden oder <div ....> tags die mit einem </div> enden.
Einfache Überprüfung ob eine eMail Adresse gültig ist:
Der Ausdruck ist wahr wenn nach jeweils 3 beliebigen Zeichen ein Punkt gesetzt ist egal wie oft hintereinander diese Regel angewendet wird.
Der Ausdruck ist wahr wenn nach jeweils 3 aaa Zeichen ein Punkt gesetzt ist, aber nur bei mindestens 3 mal.