Regex, Überblick, Begriffe, Parameter, Grundlagen und Beispiele

 

Regex ist eine universelle Beschreibungssyntax um bestimmte Teile aus Zeichenketten zu prüfen oder zu filtern. Als Beispiel könnten mit Regex sehr einfach alle <h1>-Überschriften aus einem HTML-Quellcode herausgefiltert werden. Angefangen mit PHP, habe ich Regex später auch in PowerShell und JavaScript eingesetzt. Zugegeben, anfangs habe ich Beispiele aus dem Internet für meine Einsatzzwecke angepasst und diese nur teilweise verstanden, zumal die Regex-Syntax doch irgendwie anders war, als alles mir bis dahin Bekannte. Einmal etwas tiefer damit beschäftigt, bietet Regex aber ein mächtiges Werkzeug für String Prüfungen oder Filter jeglicher Art. Mit Regex können bestimmte String-Operationen wesentlich einfacher, effizienter und eleganter umgesetzt werden. Ursprünglich in Perl eingesetzt, kann die Syntax mittlerweile zu großen Teilen in allen gängigen Skriptsprachen verwendet werden: Gängige Skriptsprachen unterstützen den Standard PCRE (Perl Compatible Regular Expressions) oder lehnen sich zumindest an dessen Syntax an.

Auch wenn die Theorie nicht unwesentlich ist, verstehe ich all jene die sich vorab lieber konkrete Beispiele ansehen wollen. Ich habe auf dieser Seite Regex-Beispiele für PHP, JavaScript und PowerShell zusammengestellt:

Die Ergebnisse der hier verwendeten Beispiele wurden mit PHP: preg_match_all oder preg_replace erzeugt und sind auch für andere Skriptsprachen gültig. Wenn die preg_match_all-Ausgabe zusätzliche Zeichenketten im Ergebnis-Array enthält, handelt es sich standardmäßig um Werte für das erste eingeklammerte Teilsuchmuster, diese werden hier, falls vorhanden, als Treffer-Gruppe1 gelistet.

Nun aber zu den Grundlagen, um Regex schneller und effizienter nutzen zu können, hier ein Überblick über die Zusammensetzung der Regex-Syntax.

Regex - Zusammensetzung

 

Zeichengruppe

(auch mehrfach hintereinander möglich: "und" bzw. mit | "oder")

 

 

Delimiter / Trennzeichen

Optional

Anker-String-Beginn

Zeichenklasse

Optional

Quantifizierer

Optional

Anker-String-Ende

Delimiter / Trennzeichen

Optional

Option

/

~

@

;

%

`

#

^

\A

.

[abc]

[a-z]

[0-9]

\w

\W

\d

+

{a,b}

{3,}

$

\Z

/

~

@

;

%

`

#

i

m

g

s

x

gm

Für die meisten Skriptsprachen wird die Regex-Such-Syntax zwischen 2 Trennzeichen (Delimiter) geschrieben ( / oder ~ oder @ ...) und am Ende der Syntax können Optionen angegeben werden. Eine Ausnahme dazu ist PowerShell. In PowerShell kann für Regex direkt die Zeichengruppe verwendet und die Option über eine Eigenschaft des Regex-Objektes festgelegt werden, siehe Regex PowerShell Optionen.

Zeichengruppen - Zeichenauswahl

In regulären Ausdrücken entsprechen die meisten Zeichen sich selbst. Als Beispiel führt das Suchen im String "ich lerne Regex", mit dem Suchbegriff "lerne", zu einem Treffer. Zusätzlich können die zu suchenden Zeichen in einer Zeichenklasse innerhalb von [ und ] zusammengefasst werden. 

Zum Beispiel entspricht eine Zeichenklasse [abc]  den folgenden Zeichen: a, b oder c. Beispiel: String: abcdefghijk... Suchpattern: [abc] Treffer: a b c
[a-z] entspricht a,b,c,d, ... z.  Beispiel: String: abcdefghijklmnopqrstuvwxyz Suchpattern: [a-z] Treffer: a b c d e f g h i j k l m n o p q r s t u v w x y z
Zeichenklassen können mit ^ negiert werden: 
[^abc] entspricht alles außer a,b,c.  Beispiel: String: abcdefghijklmnopqrstuvwxyz Suchpattern: [^abc] Treffer: d e f g h i j k l m n o p q r s t u v w x y z

Die Zeichengruppen können beliebig kombiniert werden, indem diese einfach hintereinander geschrieben werden: 

[a][0-9] ... entspricht einem a mit darauffolgend einer Zahl von 0-9: a0, a1, .... Beispiel: String: a1b2c3 Suchpattern: [a][0-9] Treffer: a1

Für ein "oder" kann ein | verwendet werden:

[a]|[0-9] ... entspricht einem a oder einer Zahl von 0-9; Beispiel:  String: a1b2c3 Suchpattern: [a]|[0-9] Treffer: a 1 2 3

Um in Regex einen Kommentar zu schreiben, kann dieser innerhalb (?# und ) hinterlegt werden, als Beispiel: String: ich lerne Regex Suchpattern: lerne(?#lerne steht für sich selbst) Treffer: lerne

Hier nochmal zusammengefasst:

Ausdruck Beschreibung Beispiel
text Ein Text entspricht sich selbst String: ich lerne Regex Suchpattern: lerne Treffer: lerne
[abc] nach bestimmten Zeichen suchen String: abcdefghijk... Suchpattern: [abc] Treffer: a b c
[a-z] Zeichen von bis .. String: abcdefghijklmnopqrstuvwxyz Suchpattern: [a-z] Treffer: a b c d e f g h i j k l m n o p q r s t u v w x y z
[^abc]  Alle Zeichen außer den angeführten String: abcdefghijklmnopqrstuvwxyz Suchpattern: [^abc] Treffer: d e f g h i j k l m n o p q r s t u v w x y z
[0-9\.\-] 0,1,2,3,4,5,6,7,8,9,.,- Nummer, Punkt oder Minus String: Text mit 123-312.123 Suchpattern: [0-9\.\-] Treffer: 1 2 3 - 3 1 2 . 1 2 3
([ab])([cd]) ac, ad, bc, oder bd String: abcdefgh Suchpattern: ([ab])([cd]) Treffer-Gruppe0: bc Treffer-Gruppe1: b
a|b oder String: abcdefgh Suchpattern: a|b Treffer: a b
[^A-Za-z0-9] Symbole die kein Buchstabe oder keine Zahl sind String: ab!cdefg?h Suchpattern: [^A-Za-z0-9] Treffer: ! ?

Neben "[", "-", "|" und "^" haben auch andere Zeichen eine besondere Bedeutung:

Zeichen mit speziellen Funktionen - Escapezeichen (Character Escapes)

Folgende Zeichen haben in Regex eine spezielle Funktion: \.*?+-[]{}|()^$.
Um diese Zeichen in Regex als Zeichen verwenden zu können, müssen diese mit einem vorangehenden \ versehen werden. Für \ also \\, bei einem Fragezeichen \? usw. 

Zeichenklassen (Character Classes)

Zeichenklasse Beschreibung Entspricht der [ ] - Zeichenklasse Beispiel
. bedeutet ein alphanumerisches Zeichen.   String: Beispiel-String Suchpattern: . Treffer: B e i s p i e l - S t r i n g
\d Dezimalziffer  [0-9] String: A847 Suchpattern: \d Treffer: 8 4 7
\D keine Dezimalziffer  [^0-9] String: A847 Suchpattern: \D Treffer: A
\w ein Buchstabe, Zahl oder Unterstrich [a-zA-Z_0-9] String: B??spiel Suchpattern: \w Treffer: B s p i e l
\W kein Buchstabe, Zahl oder Unterstrich [^a-zA-Z_0-9] String: B%?spiel Suchpattern: \W Treffer: % ?
\s Leerzeichen   String: Beispiel String Suchpattern: \s Treffer:
\S kein Leerzeichen   String: Beispiel String Suchpattern: \S Treffer: B e i s p i e l S t r i n g

Quantifizierer

Die folgenden Zeichen beeinflussen, wie oft ein Muster entsprechen soll. Die Quantifizierrer werden dazu an die Zeichengruppen oder Zeichenklassen angehängt:  

Quantifizierer Beschreibung Beispiel
+ bedeutet eines oder mehrere der vorherigen Ausdrücke String: String Suchpattern: [A-Z]+ Treffer: S
* bedeutet keines oder mehrere der vorherigen Ausdrücke (.* bedeutet also keines oder mehrere alphanumerische Zeichen. )

String: String Suchpattern: .* Treffer: String

 

?

keines oder eines der vorherigen Ausdrücke;

Non-Greedy = Lazy Matching, siehe auch: Greedy vs Non-Greedy

 String: String Suchpattern: [A-Z]? Treffer: S

{}

{3} genau 3 Vorkommen der vorherigen Ausdrücke

{3,} 3 oder mehrere Vorkommen der vorherigen Ausdrücke

{a,b} entspricht dem vorherigen Zeichen wenn es a-mal vor kommt, aber nicht öfter als b-mal.

  String: String Suchpattern: .{3} Treffer: Str ing

Greedy vs Non-Greedy oder Lazy Matching

Standardmäßig versucht Regex soviele Daten wie möglich zu finden: Greedy. Das Verhalten lässt sich am einfachsten mit einem konkreten Beispiel erklären:

Beim Extrahieren von HTML-Tags aus HTML würde per Default nur ein Treffer, zwischen dem ersten und dem letzten Tag, ausgegeben werden:
String: <html><head></head><body><h1>First Headline</h1><p>Text</p><h1>Second Headline</h1></body></html> Suchpattern: <h1>(.*)</h1> Treffer-Gruppe0: <h1>First Headline</h1><p>Text</p><h1>Second Headline</h1> Treffer-Gruppe1: First Headline</h1><p>Text</p><h1>Second Headline

Für das Extrahieren von einzelnen HTML-Tags ist das Verhalten so nicht brauchbar. Abhilfe schafft das Hinzufügen eines ? im Suchpattern: Regex verarbeitet den String dann "Non-Greedy", auch Lazy Matching genannt:
String: <html><head></head><body><h1>First Headline</h1><p>Text</p><h1>Second Headline</h1></body></html> Suchpattern: <h1>(.*?)</h1> Treffer-Gruppe0: <h1>First Headline</h1> <h1>Second Headline</h1> Treffer-Gruppe1: First Headline Second Headline

letzter Treffer

Um nach dem letzten Treffer zu suchen, kann eine negative Suche hinzugefügt werden:

String: <h1>First Headline</h1><h1>Second Headline</h1><h1>Third Headline</h1> Suchpattern: .*<h1>(.*?)</h1>(?!(\s|.)*<) Treffer-Gruppe0: <h1>First Headline</h1><h1>Second Headline</h1><h1>Third Headline</h1> Treffer-Gruppe1: Third Headline

Erklärung der zusätzlichen negativen Suche: (?!(\s|.)*<)

\s .. enspricht: Tabs, Leerzeichen, Linebreaks

(\s|.) .. Tabs, Leerzeichen, Linebreaks oder ein beliebiges Zeichen

(\s|.)* .. beliebig viele Tabs, Leerzeichen, Linebreaks oder Zeichen

(\s|.)*< .. beliebig viele Tabs, Leerzeichen, Linebreaks oder Zeichen gefolgt von einem <

?! .. negative Suche: wenn der Treffer nicht zutrifft: also

(?!(\s|.)*< .. wenn keine Tabs, Leerzeichen, Linebreaks oder Zeichen mit anschließendem < vorkommen: was als Auswahl dem letzten <h1>-Tag entspricht, bei allen anderen <h1>-Tags folgt noch ein weiterer <-Tag ..

Anker: Anchors 

Anchors beschreiben die Position im String in welcher der Treffer vorkommt

Anchor Beschreibung Beispiel
^ sucht zu Beginn des Strings

String: Beispiel-String Suchpattern: ^[A-Za-z] Treffer: B

$ Sucht am Ende des Strings

String: Beispiel-String Suchpattern: [A-Za-z]$ Treffer: g

\A Der Treffer muss am Beginn eines Strings auftreten

String: Beispiel-String Suchpattern: \A[A-Za-z] Treffer: B

\z Der Treffer muss am Ende eines Strings auftreten

String: Beispiel-String Suchpattern: [A-Za-z]\z Treffer: g

\Z Der Treffer muss am Ende eines Strings auftreten oder vor \n am Ende eines Strings

String: Beispiel-String Suchpattern: [A-Za-z]\Z Treffer: g

\G

Der Treffer startet an der Position, an der der vorige Treffer endet.

\G zwingt das Muster, nur Übereinstimmungen zurückzugeben, die Teil einer fortlaufenden Kette von Übereinstimmungen sind. Ab dem ersten Treffer muss jedem nachfolgenden Treffer ein Treffer vorausgehen. Wenn die Kette unterbrochen wird, enden die Treffer.

Folgendes Beispiel stoppt die Treffer nach dem 2ten "match":

String: match,match,not-match,match Suchpattern: (\Gmatch), Treffer-Gruppe0: match, match, Treffer-Gruppe1: match match

Im Vergleich, ohne \G würde der letzte Treffer auch verarbeitet werden:

String: match,match,not-match,match Suchpattern: (match), Treffer-Gruppe0: match, match, match, Treffer-Gruppe1: match match match

\b Der Treffer muss an einer Wortgrenze auftreten  String: Beispiel String Suchpattern: [A-Za-z]\b Treffer: l g
\B Der Treffer muss nicht an einer Wortgrenze auftreten String: Beispiel String Suchpattern: [A-Za-z]\B Treffer: B e i s p i e S t r i n

Gruppieren : Gruppierungskonstrukte (Grouping Constructs)

Das Zeichen | wird für "oder" verwendet. Zudem können Zeichen zusätzlich gruppiert werden: h(a|e)llo entspricht hallo oder hello

Ausdruck Beschreibung Beispiel
( Subausdruck )

Erfasst den übereinstimmenden Unterausdruck und weist ihm eine einbasierte Ordnungszahl zu.

String: Teesst Suchpattern: (\w)\1 Treffer-Gruppe0: ee ss Treffer-Gruppe1: e s

Erklärung \1: \Nummer : Rückverweis. Entspricht dem Wert eines nummerierten Unterausdrucks.

(?<name>Subausdruck)
oder
(?'name'Subausdruck)

Erfasst den übereinstimmenden Unterausdruck in einer benannten Gruppe.

String: Teesst Suchpattern: (?<doppelt>\w)\k<doppelt> Treffer-Gruppe0: ee ss Treffer-Gruppe1: e s

Erklärung \k<Name>: Benannter Rückverweis. Entspricht dem Wert eines benannten Ausdrucks.

String: Te12e12st Suchpattern: (?<doppelt>e[0-9]{2})\k<doppelt> Treffer-Gruppe0: e12e12 Treffer-Gruppe1: e12

(?=suche) positiv Lookahead: finde Ausdruck A wenn  Ausdruck B folgt. String: 33 und 44X. Suchpattern: [0-9]{1,}(?=X) Treffer: 44
(?<=suche) positiv Lookbehind String: X33 und 44 Suchpattern: (?<=X)[0-9]{1,} Treffer: 33
(?!=suche) negativ Lookahead: finde Ausdruck A wenn  Ausdruck B nicht folgt. String: 2ac4b Suchpattern: [0-9](?!b) Treffer: 2
(?<!suche) negativ Lookbehind String: Nummer9 hat kein a vor der Nummer a8 schon Suchpattern: (?<!a)[0-9] Treffer: 9
(?( Ausdruck ) ja | nein )

if, then, else:
wenn, dann, sonst

String: X10 B90 Y524 123 Suchpattern: (?(?=B)B[0-9]{2}\b|\b[0-9]{3}\b) Treffer: B90 123

(?<Name>Ausdruck )?( ja | nein )

der Ausdruck kann in ja mit
?(<Name>)
verwendet werden

if, then, else 
wenn 
mit Gruppennamen, dann , sonst 

String: X10 B90 Y524 123 Suchpattern: (?<BWert>B)?(?(<BWert>)[0-9]{2}\b|\b[0-9]{3}\b) Treffer-Gruppe0: B90 123 Treffer-Gruppe1: B  

String: X10 4B90 Y524 123 Suchpattern: (?<BWert>[0-9]B)?(?(<BWert>)[0-9]{2}\b|\b[0-9]{3}\b) Treffer-Gruppe0: 4B90 123 Treffer-Gruppe1: 4B  

Ersetzungen (Substitutions)

Ausdruck Beschreibung Beispiel
$Nummer Anhand von Gruppennummern ersetzen

String: eins zwei Suchpattern: \b(\w+)(\s)(\w+)\b ersetzen: $3$2$1 Ergebnis: zwei eins

Bei nur einem Treffern wird $0 verwendet.

${Name} Anhand von Gruppennamen ersetzen In PHP nicht supported 

Optionen 

Option Beschreibung
g Global: Nach dem ersten Suchtreffer weitersuchen
i Groß- und Kleinschreibung gleich behandeln. 
m Mehrzeilenmodus
s Mit dieser Option kann ein Punkt für alle Arten von Zeichen verwendet werden: Inklusive Zeilenumbrüche
x ignoriert alle Leerraumzeichen im Suchmuster.

Regex - Praxis-Beispiele für bestimmte Skriptsprachen

positive Bewertung({{pro_count}})
Beitrag bewerten:
{{percentage}} % positiv
negative Bewertung({{con_count}})

DANKE für deine Bewertung!

Fragen / Kommentare


Durch die weitere Nutzung der Seite stimmst du der Verwendung von Cookies zu Mehr Details