Regex – Quantifier

6 Kernkonzepte
Die wichtigsten Quantifier für reguläre Ausdrücke im Detail: * · + · ? · {n,m} · Greedy vs. Lazy · Possessive Quantifier legen fest, wie oft ein Zeichen oder eine Gruppe wiederholt werden darf. Dieses Cheatsheet erklärt die Unterschiede zwischen Greedy, Lazy und Possessive Quantifiern mit praktischen Beispielen.

Grundlegende Quantifier – *, +, ?, {n,m}

* · + · ? · {n} · {n,m} · {n,}
// Die grundlegenden Quantifier a* // 0 oder mehr (beliebig viele) a+ // 1 oder mehr (mindestens einmal) a? // 0 oder 1 (optional) a{5} // exakt 5 Mal a{2,5} // 2 bis 5 Mal a{2,} // mindestens 2 Mal a{,5} // 0 bis 5 Mal

Grundlegende Quantifier definieren die minimale und maximale Anzahl von Wiederholungen eines Zeichens oder einer Gruppe.

Beispiele
# * = 0 oder mehr
bo*b, bo, boo, booo
# + = 1 oder mehr
bo+bo, boo, booo (nicht b)
# ? = 0 oder 1
colou?rcolor, colour
# {n} = exakte Anzahl
\d{5}12345, 67890
# {n,m} = Bereich
\d{2,4}12, 123, 1234
Tipp: ? macht ein Zeichen optional. Es ist äquivalent zu {0,1}. * ist äquivalent zu {0,} und + zu {1,}.

Greedy Quantifier – So viel wie möglich

.* · .+ · .? · .{n,m}
// Greedy Quantifier (Standard) .* // 0 oder mehr (so viel wie möglich) .+ // 1 oder mehr (so viel wie möglich) .*? // Lazy (so wenig wie möglich) – siehe nächste Karte

Greedy Quantifier versuchen, so viele Zeichen wie möglich zu matchen, während das gesamte Pattern noch erfolgreich ist. Sie sind der Standard in den meisten Regex-Engines.

Beispiele
# Text: <p>Absatz 1</p><p>Absatz 2</p>
# Greedy: matcht den gesamten String
<p>.*</p><p>Absatz 1</p><p>Absatz 2</p>
# Greedy bei Zahlen
\d+ auf "123abc456"123 (erstes Match)
# Greedy: matcht die längste Zahl
\d{2,4} auf "12345"1234 (4 statt 2 oder 3)
Tipp: Greedy Quantifier können bei unerwarteten Ergebnissen zu "Überraschungen" führen – besonders bei HTML/XML-Parsing. Verwenden Sie Lazy Quantifier, wenn Sie das kleinste Match wollen.

Lazy Quantifier – So wenig wie möglich

*? · +? · ?? · {n,m}?
// Lazy Quantifier (nicht-gierig) *? // 0 oder mehr (so wenig wie möglich) +? // 1 oder mehr (so wenig wie möglich) ?? // 0 oder 1 (so wenig wie möglich) {n,m}? // n bis m (so wenig wie möglich)

Lazy Quantifier (auch "non-greedy" oder "reluctant") versuchen, so wenig Zeichen wie möglich zu matchen, während das gesamte Pattern noch erfolgreich ist.

Beispiele
# Text: <p>Absatz 1</p><p>Absatz 2</p>
# Lazy: matcht nur das erste <p>-Tag
<p>.*?</p><p>Absatz 1</p>
# Lazy bei Zahlen
\d+? auf "123abc"1 (nur eine Ziffer)
# Lazy: matcht die kürzeste Zahl
\d{2,4}? auf "12345"12 (2 statt 4)
Tipp: Lazy Quantifier sind essentiell für das Parsen von strukturierten Texten wie HTML, XML oder JSON, wo Sie nur den nächsten Tag oder das nächste Element erfassen möchten.

Possessive Quantifier – Besitzergreifend

*+ · ++ · ?+ · {n,m}+
// Possessive Quantifier (besitzergreifend) *+ // 0 oder mehr (kein Backtracking) ++ // 1 oder mehr (kein Backtracking) ?+ // 0 oder 1 (kein Backtracking) {n,m}+ // n bis m (kein Backtracking)

Possessive Quantifier sind wie Greedy Quantifier, aber sie geben einmal gefundene Zeichen nie wieder zurück (kein Backtracking). Sie sind schneller, können aber zu fehlenden Matches führen.

Beispiele
# Possessive: matcht alles oder nichts
".*+" auf "text""text" (funktioniert)
# Problem: Possessive verhindert Backtracking
".*+" auf "text" → matcht nicht, wenn das Pattern mehr erwartet
# Vergleich: Greedy vs. Possessive
a++b auf "aaa"kein Match (a++ verbraucht alle a's)
a+b auf "aaa"kein Match (gleiches Ergebnis)
# Performance: Possessive ist schneller bei großen Texten
(a++|b+)c → kein Backtracking, daher effizienter
Tipp: Possessive Quantifier sind nützlich für Performance-Optimierungen bei großen Texten, wenn Sie sicher sind, dass kein Backtracking benötigt wird. Sie werden in JavaScript nicht unterstützt (nur in PCRE, Java, .NET).

Vergleich – Greedy · Lazy · Possessive

.* · .*? · .*+
// Drei Quantifier-Typen im Vergleich .* // Greedy: so viel wie möglich (Backtracking) .*? // Lazy: so wenig wie möglich (Backtracking) .*+ // Possessive: so viel wie möglich (kein Backtracking)

Greedy, Lazy und Possessive Quantifier bestimmen, wie viel Text von einem Quantifier erfasst wird. Die Wahl beeinflusst das Ergebnis und die Performance.

Vergleichstabelle

Quantifier Typ Backtracking Match-Verhalten Performance
.* Greedy Ja So viel wie möglich Mittel
.*? Lazy Ja So wenig wie möglich Mittel (oft langsamer)
.*+ Possessive Nein So viel wie möglich (ohne Zurückgeben) Schnell
.+ Greedy Ja 1 oder mehr (so viel wie möglich) Mittel
.+? Lazy Ja 1 oder mehr (so wenig wie möglich) Mittel
.++ Possessive Nein 1 oder mehr (ohne Zurückgeben) Schnell
Beispiel mit Erklärung
# Text: "123abc456"
# Greedy: matcht die längste Zahl
\d+123 (erstes Match)
# Lazy: matcht die kürzeste Zahl
\d+?1 (nur eine Ziffer)
# Possessive: matcht alles oder nichts
\d++123 (verbraucht alle Ziffern, gibt nichts zurück)
# Mit Follow-Pattern: possessive kann fehlschlagen
\d++b auf "123a"kein Match (weil b fehlt und keine Rückgabe möglich)
Tipp: Verwenden Sie Greedy für die meisten Anwendungen. Lazy für strukturierte Texte (HTML). Possessive für Performance-kritische Anwendungen, wenn Sie Backtracking vermeiden möchten.

Praxisbeispiele – Anwendung der Quantifier

E-Mail · URL · Datum · HTML
// Typische Anwendungen \b[a-z]+@[a-z]+\.[a-z]{2,}\b // Einfache E-Mail https?://[^\s]+ // URL \d{4}-\d{2}-\d{2} // Datum (YYYY-MM-DD) <[^>]+> // HTML-Tags (einfach)

Praxisbeispiele zeigen, wie Quantifier in realen Szenarien eingesetzt werden – von der E-Mail-Validierung bis zum HTML-Parsing.

Beispiele
# E-Mail (einfach)
\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}\b
# URL (HTTP/HTTPS)
https?://[^\s]+
# Datum (YYYY-MM-DD) mit Greedy
\d{4}-\d{2}-\d{2}2024-12-31
# HTML-Tag mit Lazy (wichtig!)
<[^>]+><tag> (matcht nur ein Tag)
# Telefonnummer (Deutschland) mit Quantifiern
\+49[0-9]{3}[0-9]{8,9}
# Wiederholende Muster mit Gruppen
(ab){2,4}abab, ababab, abababab
Tipp: Für komplexe E-Mail-Validierung verwenden Sie keine zu komplizierten Regex – E-Mails sind extrem komplex. Nutzen Sie einfache Pattern und validieren Sie die Domain separat.

Quantifier im Überblick

* 0 oder mehr
Greedy, Backtracking
+ 1 oder mehr
Greedy, Backtracking
? 0 oder 1
Greedy, Backtracking
*? 0 oder mehr (lazy)
So wenig wie möglich
*+ 0 oder mehr (possessive)
Kein Backtracking
{n,m} n bis m Mal
Exakte Steuerung

Quick Summary

* + ?
Grundlegend
.*
Greedy (viel)
.*?
Lazy (wenig)
.*+
Possessive (schnell)
G vs L vs P
Vergleich
Beispiele
Praxis
.* (Greedy) · .*? (Lazy) · .*+ (Possessive) · {2,5} (Bereich)