Begriff
Regex (Regular Expression)
Warum wichtig?
Dieser Begriff ist ein Knoten im SengakujiWorks-Wissensnetz. Nutze Level 0 für die erste Einordnung, Level 1 für Praxis, Level 2 für technische Struktur und Level 3 für Grenzen, Fallstricke und Expertenkontext.
Ein Super-Suchwerkzeug.
Normales Suchen: "Finde 'Meier'".
Regex Suchen: "Finde alle Wörter, die mit M anfangen, 5 Buchstaben haben und mit r enden". (M...r).
Oder: "Finde alle Email-Adressen". (.+@.+\..+).
Es ist eine eigene, extrem kompakte Sprache für Mustererkennung.
Sie sieht kryptisch aus (^([a-z0-9_\.-]+)@...), ist aber extrem mächtig.
Merksatz: Eine Zeichenkette, die ein Suchmuster definiert, um Texte zu validieren, zu durchsuchen oder zu verändern.
Die wichtigsten Bausteine:
.- Irgendein Zeichen.\d- Eine Ziffer (0-9).\w- Ein Wort-Zeichen (a-z, 0-9, _).+- Eines oder mehr davon (\d+= "Zahl beliebiger Länge").*- Null oder mehr.?- Optional.^/$- Anfang / Ende der Zeile.
Validierung einer Postleitzahl (5 Ziffern): ^\d{5}$.
1. Capture Groups
Du willst aus "Datum: 2023-10-27" nur das Jahr extrahieren.
Regex: Datum: (\d{4})-.*
Die Klammern (...) fangen den Inhalt.
Das Ergebnis ist Gruppe 1: "2023".
Mit Release 2023 in Suchen/Ersetzen kann man komplexe Texte umbauen.
2. Greedy vs. Lazy
Standardmäßig ist Regex gierig (Greedy).
Text: <a>Test</a>
Regex: <.*>
Was findet er? Den ganzen String <a>Test</a>! Weil * so weit frisst wie möglich.
Lösung Lazy: <.*?>. Das ? sagt: "Nimm so wenig wie möglich."
Ergebnis: <a> und </a>.
3. ReDoS (Regex Denial of Service)
Ein böser User gibt eine Email ein: aaaaaaaaaaaaaaaaaaaa!.
Deine Regex ist schlecht gebaut (Catastrophic Backtracking).
Der Server braucht 100% CPU für 10 Minuten, um zu prüfen, ob das eine Email ist.
Hacker legen so Server lahm.
Keine verschachtelten Quantifizierer nutzen (a+)+!
NFA vs. DFA Engines (Unter der Haube)
Es gibt prinzipiell zwei Arten, wie Programmiersprachen Regex ausführen.
DFA (Deterministic Finite Automaton): Genutzt in awk oder grep. Der Algorithmus wertet den Test-String exakt einmal linear O(N) aus. Superschnell, nie ReDoS, unterstützt aber keine Backreferences (wie "Finde Gruppe 1 nochmal").
NFA (Nondeterministic Finite Automaton): Genutzt in Python, Java, JS. Der Automat hangelt sich den Regex-Ausdruck entlang. Fällt er in eine Sackgasse, kehrt er um (Backtracking) und versucht den vorherigen Zweig anders zu matchen. NFA ist mächtiger (erlaubt Capture Groups und Lookarounds), neigt aber beim Catastrophic Backtracking zu exponentiellem Zeit-Schrecken (ReDoS).
Atomic Groups & Possessive Quantifiers
Wenn man in anfälligen NFA-Engines Optimierungen zwingen muss, nutzt man Atomic Groups (?>...) oder possessive Quantoren (++, *+).
Ein normales .* frisst "gierig" alles bis zum Ende, gibt dann Zeichen für Zeichen zurück (Backtracking), bis es passend abschließt.
Ein possessives .*+ frisst dogmatisch alles – und weigert sich stur, auch nur einen Millimeter zurückzugehen! Trifft der Regex auf eine Wand, bricht er den gesamten Ast sofort mit Fehlgeschlagen ab. Wenn man sicher ist, wie der String formatiert ist, verhindert das Atomic/Possessive Pattern 100% aller ReDoS-Attacken im Parser.
Lookaround (Die unsichtbaren Anker)
Lookarounds verändern mächtig das Suchverhalten: Sie matchen Positionen, konsumieren das Zeichen aber nicht (Zero-Width Assertions).
- Positive Lookahead
(?=X): "Finde Z, aber nur wenn danach ein X kommt." Das X ist nach dem Match noch auswertbar für die nächste Regex-Operation. - Negative Lookbehind
(?<!Y): "Finde Z, aber verweigere, wenn kurz vorher ein Y stand." Gerade Parsing-Aufgaben ("Suche alle Passwörter, die nicht in HTML Tags stehen") sind ohne Lookarounds unmöglich, da reguläre Zeichen sonst durch den Match einfach übersprungen (verzehrt) würden.
Quick-Check
Wann NICHT nutzen?
HTML parsen. "Du kannst HTML nicht mit Regex parsen." HTML ist verschachtelt, Regex ist linear. Nutze einen HTML-Parser (DOM).Lookahead / Lookbehind?
Mächtiges Feature. "Finde 'Euro', aber nur, wenn davor ein Zahl steht ((?<=\d)Euro)." Das Pattern matcht, aber "frisst" die Zahl nicht.Glob vs Regex?
Glob (*.txt) ist die Dateisuche im Terminal. Viel einfacher, viel weniger mächtig als Regex.