Developer Tools

Reguläre Ausdrücke (Regex) verständlich erklärt: Syntax und ReDoS-Schutz

Ein regulärer Ausdruck (oft abgekürzt als Regex oder RegExp) ist eine Zeichenkette, die ein Suchmuster beschreibt. Mithilfe dieses Musters können Programme Texte durchsuchen, Eingaben validieren oder Zeichenfolgen manipulieren. Obwohl Regex ein extrem mächtiges Werkzeug ist, führt eine ineffiziente Formulierung schnell zu Performance-Problemen oder schwerwiegenden Sicherheitslücken.

Reguläre Ausdrücke begegnen Entwicklern überall: bei der Validierung von Formulareingaben, beim Extrahieren von Werten aus Logdateien oder beim Suchen-und-Ersetzen in der IDE. Wer regelmässig mit strukturierten Daten arbeitet, kombiniert Regex häufig mit Werkzeugen zum JSON-Formatieren oder zum Dekodieren von JSON Web Tokens, um bestimmte Felder gezielt herauszuziehen.

Die grundlegende Syntax regulärer Ausdrücke

Reguläre Ausdrücke bestehen aus einer Kombination von literalen Zeichen (die exakt mit sich selbst übereinstimmen) und Metazeichen (die eine Sonderbedeutung haben).

1. Zeichenklassen (Character Classes)

Mit eckigen Klammern wird definiert, welche Zeichen an einer bestimmten Stelle erlaubt sind:

  • [abc]: Entspricht entweder a, b oder c.
  • [a-z]: Entspricht jedem Kleinbuchstaben von a bis z.
  • [^0-9]: Das Caret-Symbol ^ am Anfang einer Klasse negiert diese; hier entspricht es jedem Zeichen, das keine Ziffer ist.

Es gibt vordefinierte Abkürzungen für häufige Zeichenklassen:

  • \d: Jede Ziffer (entspricht [0-9]).
  • \w: Jedes Wortzeichen (Buchstaben, Ziffern und Unterstrich; entspricht [a-zA-Z0-9_]).
  • \s: Jedes Whitespace-Zeichen (Leerzeichen, Tabulator, Zeilenumbruch).

2. Quantoren (Quantifiers)

Quantoren legen fest, wie oft das vorhergehende Zeichen oder die vorhergehende Gruppe vorkommen darf:

  • *: Null oder mehrfach.
  • +: Ein- oder mehrfach.
  • ?: Null- oder einmal (macht das Zeichen optional).
  • {n}: Exakt n-mal.
  • {n,m}: Mindestens n-mal und maximal m-mal.

3. Anker (Anchors)

Anker passen nicht auf Zeichen, sondern auf Positionen im Text:

  • ^: Entspricht dem Anfang der Zeichenkette.
  • $: Entspricht dem Ende der Zeichenkette.
  • \b: Entspricht einer Wortgrenze.

Die wichtigsten Metazeichen auf einen Blick

Für den schnellen Einstieg fasst die folgende Tabelle die am häufigsten benötigten Bausteine zusammen:

KonstruktBedeutungBeispielTrifft auf
.Beliebiges Zeichen (ausser Zeilenumbruch)a.cabc, axc
\dEine Ziffer\d{4}2026
\wWortzeichen\w+Hallo_1
[a-z]Zeichenbereich[a-f]c
|Alternative (oder)rot|blaurot oder blau
()Gruppierung / Erfassung(ab)+abab
?Optional / genügsamcolou?rcolor, colour

Praxisbeispiele: bewährte Muster

In der täglichen Arbeit wiederholen sich einige typische Validierungs- und Extraktionsmuster. Die folgende Tabelle zeigt erprobte, robuste Ausdrücke:

AnwendungsfallRegulärer AusdruckErläuterung
E-Mail (grobe Prüfung)^[^@\s]+@[^@\s]+\.[^@\s]+$Lokalteil, @, Domain mit Punkt
Schweizer PLZ^[1-9]\d{3}$Vier Ziffern, nicht mit 0 beginnend
Datum (ISO 8601)^\d{4}-\d{2}-\d{2}$JJJJ-MM-TT
Hex-Farbe^#?[0-9a-fA-F]{6}$Sechs Hex-Zeichen, optionales #
IPv4-Oktett (vereinfacht)\b\d{1,3}(\.\d{1,3}){3}\bVier durch Punkte getrennte Zahlen

Wer ganze IP-Bereiche statt einzelner Adressen prüfen möchte, ist mit der CIDR-/Subnetz-Notation besser bedient als mit einer komplexen Regex.


Funktionsweise der Regex-Engines: DFA vs. NFA

Es gibt zwei grundlegende Typen von Regex-Engines, die reguläre Ausdrücke auswerten:

  1. DFA (Deterministic Finite Automaton): Diese Engines lesen den Eingabetext Zeichen für Zeichen genau einmal. Sie laufen in linearer Zeit O(N) ab, unterstützen jedoch keine fortgeschrittenen Funktionen wie Backreferences (Rückwärtsreferenzen) oder Lookarounds (Vorausblick/Rückblick).
  2. NFA (Nondeterministic Finite Automaton): Fast alle modernen Programmiersprachen (JavaScript, Python, Java, .NET, PHP/PCRE) nutzen NFA-Engines. Sie arbeiten wegbasiert: Sie versuchen, das Muster auf den Text anzuwenden. Schlägt ein Weg fehl, springen sie im Text zurück und probieren den nächsten Pfad aus (Backtracking).

Die Gefahr von ReDoS (Regular Expression Denial of Service)

Da NFA-Engines auf Backtracking setzen, kann die Auswertungszeit bei unglücklich gewählten Ausdrücken und bestimmten Eingaben exponentiell ansteigen. Dies wird als katastrophales Backtracking bezeichnet.

Beispiel für katastrophales Backtracking

Betrachten wir den Ausdruck: ^(a+)+$

Dieser Ausdruck besagt: Beginne am Zeilenanfang, finde ein oder mehrere as, gruppiere sie, wiederhole diese Gruppe ein- oder mehrfach und ende am Zeilenende.

  • Bei der Eingabe aaaa gibt es viele verschiedene Wege, wie die NFA-Engine die as aufteilen kann (z. B. [aaaa], [aaa][a], [aa][aa], [a][a][a][a]). Da der String am Ende mit der Eingabe übereinstimmt, bricht die Engine schnell erfolgreich ab.
  • Bei der Eingabe aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!: Hier folgt am Ende ein Ausrufezeichen, das nicht auf das Dollarzeichen (Zeilenende) nach den as passt. Die Engine muss nun jeden einzelnen der Millionen von Kombinationspfaden durchlaufen und zurückverfolgen (Backtracking), um sicherzugehen, dass es wirklich keine Übereinstimmung gibt.
  • Die Anzahl der Schritte wächst exponentiell ($2^N$ mit der Länge der Kette N). Bereits bei etwa 30 bis 40 as blockiert ein einzelner Thread des Webservers für mehrere Minuten die CPU zu 100 %.

Prävention im Code

  • Verschachtelte Quantoren vermeiden: Konstrukte wie (a+)+ oder (a|b*)* sind extrem gefährlich.
  • Timeouts verwenden: Konfigurieren Sie Timeouts für Regex-Auswertungen (z. B. in .NET Regex(pattern, options, matchTimeout)).
  • DFA-basierte Bibliotheken nutzen: Verwenden Sie Bibliotheken wie Googles RE2 (oder das regex-Crate in Rust), die kein Backtracking durchführen und garantiert in linearer Zeit abschliessen.

[!TIP] Möchten Sie reguläre Ausdrücke auf Syntaxfehler prüfen, Testtexte abgleichen oder Ihre Ausdrücke auf Stabilität testen? Nutzen Sie den kostenlosen Regex Tester auf balou.tools für eine bequeme und sichere Analyse direkt in Ihrem Browser.

Häufig gestellte Fragen (FAQ)

Was ist ReDoS (Regular Expression Denial of Service)?

ReDoS ist eine Sicherheitslücke, bei der ein ineffizienter regulärer Ausdruck bei bestimmten Eingaben extrem lange zur Auswertung benötigt (katastrophales Backtracking). Angreifer können dies ausnutzen, um die CPU des Servers zu 100 % auszulasten und den Dienst lahmzulegen.

Wie kann ich ReDoS-Lücken verhindern?

Vermeiden Sie verschachtelte Quantoren (wie `(a+)+`) und sich überschneidende Muster im Ausdruck. Setzen Sie zudem in Ihrer Programmiersprache Timeouts für die Regex-Auswertung oder nutzen Sie Engines wie RE2, die lineares Laufzeitverhalten garantieren.

Was ist der Unterschied zwischen gierigen und genügsamen Quantoren?

Ein gieriger Quantor (`.*`) versucht, so viel Text wie möglich zu erfassen, und gibt erst beim Backtracking wieder Zeichen frei. Ein genügsamer (lazy) Quantor (`.*?`) erfasst so wenig wie möglich. Beim Parsen von HTML- oder JSON-Fragmenten verhindert die genügsame Variante, dass ein Muster versehentlich über mehrere Elemente hinweg greift.

Sollte man E-Mail-Adressen mit Regex validieren?

Nur grob. Eine vollständig RFC-konforme E-Mail-Regex ist extrem komplex und fehleranfällig. In der Praxis genügt ein einfaches Muster wie `^[^@\s]+@[^@\s]+\.[^@\s]+$` zur Formatprüfung; die tatsächliche Existenz der Adresse lässt sich ohnehin nur durch das Versenden einer Bestätigungs-E-Mail nachweisen.