Reguläre Ausdrücke erklärt: Klassen, Quantoren und Gruppen

Aktualisiert:

Ein regulärer Ausdruck, kurz Regex, ist ein kleines Muster, das Text beschreibt: „vier Ziffern, ein Bindestrich, zwei Ziffern“ oder „ein Wort, das mit einem Großbuchstaben beginnt“. Programme nutzen sie zum Suchen, zum Prüfen von Eingaben und zum Herauslösen von Teilen einer Zeile. Dieser Ratgeber erklärt die Bausteine eines Musters mit Beispielen, die Sie in den Regex-Tester einfügen können, und danach die Fallen: Muster, die mehr finden als gedacht, Muster, die ewig laufen können, und die Unterschiede zwischen den Regex-Engines von JavaScript, Python und PHP. Die Beispiele verwenden die Syntax von JavaScript, die der Tester und jeder Browser ausführen.

Zeichen, die etwas anderes bedeuten

Die meisten Zeichen in einem Muster stehen für sich selbst: Tag findet die Buchstaben T, a und g in dieser Reihenfolge. Vierzehn nicht, weil sie im Muster eine Aufgabe haben: . ^ $ * + ? ( ) [ ] { } | \ und, im JavaScript-Code, der Schrägstrich, der das Muster beendet. Um eines davon wörtlich zu finden, setzen Sie einen Backslash davor.

Zeichenklassen

Eine Klasse findet ein Zeichen aus einer Menge. Eckige Klammern zählen die Menge selbst auf; ein Backslash mit einem Buchstaben liefert eine fertige; der Großbuchstabe bedeutet das Gegenteil.

MusterFindet ein…
[aeiou]Vokal ohne Umlaut: a, e, i, o oder u
[^aeiou]Zeichen, das keines davon ist, auch Leerzeichen und Ziffern
[a-z0-9]Kleinbuchstabe von a bis z oder eine Ziffer
\dZiffer von 0 bis 9 (\D: alles andere)
\wBuchstabe von A bis Z oder a bis z, Ziffer oder Unterstrich (\W: alles andere)
\sLeerzeichen, Tabulator, Zeilenumbruch oder anderen Leerraum (\S: alles andere)
.Zeichen außer einem Zeilenumbruch (mit dem Flag s jedes Zeichen)
\p{L}Buchstabe aus jedem Alphabet, mit dem Flag u oder v

In JavaScript kennen \d und \w nur das lateinische Grundalphabet: \w+ zerlegt Straße in Stra und e, und \d findet die ostarabische Ziffer ٣ nicht. Mit dem Flag u findet \p{L}+ Straße als Ganzes und \p{Nd} Ziffern jeder Schrift. Python 3 macht es umgekehrt: Bei normalem Text decken sein \d und sein \w Unicode bereits ab, außer mit dem Flag ASCII. Die PCRE2-Engine von PHP bleibt bei ASCII, solange die Unicode-Eigenschaften nicht eingeschaltet sind, etwa mit (*UCP) am Anfang des Musters.

Quantoren: wie oft

Ein Quantor gibt an, wie oft das Element davor vorkommen darf. Er gilt für ein Zeichen, eine Klasse oder eine Gruppe in Klammern.

MusterBedeutet
a*null oder mehr
a+eins oder mehr
a?null oder eins, also optional
a{3}genau drei
a{3,}drei oder mehr
a{2,4}zwei bis vier

Quantoren sind gierig: Sie nehmen so viel wie möglich und geben nur ab, was der Rest des Musters braucht. Bei <b>fett</b> findet das Muster <.+> die ganze Zeichenkette, vom ersten < bis zum letzten >. Ein Fragezeichen dahinter macht den Quantor genügsam, er nimmt so wenig wie möglich: <.+?> findet <b> und dann </b>. colou?r findet beide englischen Schreibweisen, color und colour, und \d{3,} findet Zahlen mit drei oder mehr Ziffern.

Anker und Wortgrenzen

Anker finden eine Position, kein Zeichen. ^ ist der Anfang des Textes und $ das Ende; mit dem Flag m werden sie zu Anfang und Ende jeder Zeile. \b ist eine Wortgrenze, die Stelle zwischen einem Wortzeichen und etwas anderem, daher findet \bTag\b das Wort Tag, aber nicht in Tagung. Ohne Anker akzeptiert ein Muster zur Prüfung auch Text mit zusätzlichen Zeichen um den passenden Teil: \d{4} findet vier Ziffern in abc12345, ^\d{4}$ dagegen nur genau vier Ziffern.

Gruppen, Alternativen und Rückverweise

Klammern fassen einen Teil des Musters zusammen, damit ein Quantor oder eine Alternative für den ganzen Teil gilt, und sie halten den gefundenen Text fest, damit ein Programm ihn lesen kann: (\d{4})-(\d{2})-(\d{2}) erfasst Jahr, Monat und Tag getrennt. (?:…) gruppiert ohne zu erfassen, und (?<jahr>\d{4}) gibt der Erfassung einen Namen.

Der senkrechte Strich bedeutet „oder“ und bindet am schwächsten: ^Tag|nacht$ heißt „Tag am Anfang“ oder „nacht am Ende“, findet also Tag in Tagung und nacht in Mitternacht. Für „der ganze Text ist Tag oder nacht“ gruppieren Sie die Alternativen: ^(?:Tag|nacht)$.

Ein Rückverweis findet denselben Text, den eine Gruppe schon erfasst hat: (\w)\1 findet einen Buchstaben, auf den er selbst folgt, ff und ee in Kaffeemaschine, und \k<name> tut dasselbe für eine benannte Gruppe.

Lookahead und Lookbehind

Ein Lookaround prüft, was vor oder nach einer Position steht, ohne es in den Treffer aufzunehmen. (?=…) verlangt, dass etwas folgt, (?!…) verbietet es; (?<=…) verlangt, dass etwas vorangeht, (?<!…) verbietet es. Damit lässt sich eine Zahl an ihrer Einheit oder Währung erkennen, oder man stapelt mehrere Bedingungen auf denselben Text.

Flags

Flags ändern, wie das ganze Muster angewendet wird. In JavaScript stehen sie hinter dem schließenden Schrägstrich, wie in /Tag/gi; im Tester haben sie ein eigenes Feld.

FlagWirkung
galle Treffer finden, nicht nur den ersten
iGroß- und Kleinschreibung nicht unterscheiden
m^ und $ gelten für jede Zeile
sder Punkt findet auch Zeilenumbrüche
uUnicode-Modus: \p{…}, und ein Emoji zählt als ein Zeichen
vUnicode-Modus mit Mengenoperationen in Klassen; statt u verwenden
yhaftend: nur dort suchen, wo der vorige Treffer endete
dfesthalten, wo jede Gruppe beginnt und endet

E-Mails, Datumsangaben und andere Formate prüfen

Eine Regex kann die Form einer Eingabe prüfen, nicht ob sie stimmt. Der HTML-Standard legt mit einem eigenen Muster fest, was ein <input type="email"> annimmt, und sagt offen, dass er damit bewusst von RFC 5322 abweicht, dem Standard für das E-Mail-Format, der Formen wie Namen in Anführungszeichen mit Leerzeichen erlaubt, die fast niemand nutzt. Es akzeptiert ana@example.com und auch ana@localhost; es lehnt ana@my_domain.example ab, weil ein Domainname keinen Unterstrich enthalten darf. Ob das Postfach existiert, zeigt nur eine Nachricht.

Bei Datumsangaben ist es ähnlich: ^\d{4}-\d{2}-\d{2}$ akzeptiert 2026-02-31, den es nicht gibt. Prüfen Sie die Form mit dem Muster und lassen Sie dann eine Datumsfunktion entscheiden, ob das Datum gültig ist. Und zerlegen Sie HTML oder JSON nicht mit regulären Ausdrücken: Verschachtelte Strukturen brauchen einen Parser.

Wenn ein Muster nicht mehr fertig wird

Die meisten Engines, auch die von JavaScript, Python und PHP, arbeiten mit Backtracking: Scheitert ein Weg, gehen sie zurück und versuchen eine andere Aufteilung des Textes auf die Teile des Musters. Eine Gruppe, die etwas wiederholt, das sich selbst wiederholt, wie ^(a+)+$, lässt sich auf eine Zahl von Arten aufteilen, die sich mit jedem weiteren Zeichen verdoppelt. Bei einer Reihe von a mit einem Ausrufezeichen am Ende kann das Muster nie passen, aber die Engine probiert jede Aufteilung, bevor sie aufgibt. OWASP nennt das einen Denial of Service durch reguläre Ausdrücke, ReDoS, und nennt Muster wie (a+)+$, ([a-zA-Z]+)*$ und (a|aa)+$.

Abhilfe schafft, die Mehrdeutigkeit zu beseitigen: ^a+$ beschreibt denselben Text und scheitert sofort. Vermeiden Sie verschachtelte Quantoren und Alternativen, die dieselben Zeichen finden können, und führen Sie ein Muster von Nutzern nie ohne Zeitlimit aus. Der Regex-Tester startet jede Suche in einem eigenen Worker und hält sie nach einer halben Sekunde an, sodass ein solches Muster gemeldet wird, statt die Seite einzufrieren.

Regex-Tester

Nicht jede Engine ist gleich

Die Grundlagen oben gelten fast überall, die Einzelheiten ändern sich aber von Sprache zu Sprache. Ein Muster, das für eine Engine geschrieben wurde, sollte in der anderen getestet werden, bevor man sich dort darauf verlässt.

FunktionJavaScriptPython (re)PHP (PCRE2)
Benannte Gruppe(?<name>…)(?P<name>…)beide Formen
\d und \wnur ASCIIstandardmäßig UnicodeASCII, außer mit UCP
Possessive Quantoren und atomare Gruppen (a++, (?>…))neinja, seit Python 3.11ja
Inline-Flags wie (?i)nur die begrenzte Form (?i:…), seit ECMAScript 2025jaja

Auch der Lookbehind unterscheidet sich: JavaScript akzeptiert einen mit veränderlicher Länge, etwa (?<=[a-z]+), Python verlangt eine feste Breite und lehnt ihn ab. Python schreibt außerdem die Backslashes im Code anders: Ein Raw-String, r"\d+", behält sie wie getippt, während JavaScript-Muster zwischen Schrägstrichen keine Verdopplung brauchen. In einem JavaScript-String, der an new RegExp() geht, muss jeder Backslash doppelt geschrieben werden.

Häufige Fragen

Warum findet mein Muster nur einen Treffer?

In JavaScript endet die Suche beim ersten Treffer, wenn das Flag g fehlt. Ergänzen Sie im Tester g bei den Flags.

Warum findet \w keine Umlaute und kein ß?

Weil \w in JavaScript nur A bis Z, a bis z, Ziffern und den Unterstrich meint. Verwenden Sie \p{L} mit dem Flag u für Buchstaben aller Alphabete.

Wie finde ich einen Punkt, eine Klammer oder ein Fragezeichen?

Setzen Sie einen Backslash davor: \. \( \? und so weiter. In eckigen Klammern verlieren die meisten ihre Bedeutung, daher findet [.?] einen Punkt oder ein Fragezeichen.

Kann ein regulärer Ausdruck eine E-Mail-Adresse prüfen?

Nur ihre Form. Das Muster des HTML-Standards ist für Formulare eine gute Wahl; ob die Adresse Post empfängt, zeigt nur eine gesendete Nachricht.

Warum hat mein Muster das Programm hängen lassen?

Es wiederholt vermutlich eine Gruppe, die sich selbst wiederholt, etwa (a+)+, und der Text passt fast. Schreiben Sie es ohne verschachtelte Quantoren und führen Sie Muster von Nutzern mit Zeitlimit aus.

Quellen

  1. MDN Web Docs — Regular expressions (JavaScript guide)
  2. MDN Web Docs — Regular expression syntax cheat sheet
  3. ECMAScript® Language Specification — RegExp (Regular Expression) Objects
  4. TC39 — Finished proposals (RegExp modifiers and duplicate named groups: ECMAScript 2025)
  5. Python documentation — re: regular expression operations
  6. PCRE2 — pcre2pattern: syntax and semantics of the regular expressions
  7. OWASP — Regular expression Denial of Service (ReDoS)
  8. WHATWG HTML Standard — Valid email address
  9. RFC 5322 — Internet Message Format (October 2008)

Weitere Ratgeber