Reguläre Ausdrücke erklärt: Klassen, Quantoren und Gruppen
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.
1.5Findet 1.5, aber auch 1x5 und 1-5: Der Punkt steht für ein beliebiges Zeichen.1\.5Findet nur 1.5: Der Backslash macht den Punkt zu einem Punkt.\$\d+Findet $30: ein maskiertes Dollarzeichen, dann Ziffern.
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.
| Muster | Findet 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 |
\d | Ziffer von 0 bis 9 (\D: alles andere) |
\w | Buchstabe von A bis Z oder a bis z, Ziffer oder Unterstrich (\W: alles andere) |
\s | Leerzeichen, 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.
| Muster | Bedeutet |
|---|---|
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.
\bTag\bBei „Tag Tagung Tag.“: zwei Treffer, die beiden Wörter Tag.^\d{4}$Akzeptiert 2026; lehnt 12026 und 2026a ab.
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.
\d+(?=%)Bei „20% von 500“: findet 20, die Zahl vor einem Prozentzeichen, ohne das Zeichen.(?<=€)\d+Bei „€25 und $30“: findet 25, den Betrag nach einem Eurozeichen.^(?=.*\d).{8,}$Akzeptiert Passwort1 und lehnt Passwort ab: mindestens acht Zeichen, darunter eine Ziffer.
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.
| Flag | Wirkung |
|---|---|
g | alle Treffer finden, nicht nur den ersten |
i | Groß- und Kleinschreibung nicht unterscheiden |
m | ^ und $ gelten für jede Zeile |
s | der Punkt findet auch Zeilenumbrüche |
u | Unicode-Modus: \p{…}, und ein Emoji zählt als ein Zeichen |
v | Unicode-Modus mit Mengenoperationen in Klassen; statt u verwenden |
y | haftend: nur dort suchen, wo der vorige Treffer endete |
d | festhalten, 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.
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.
| Funktion | JavaScript | Python (re) | PHP (PCRE2) |
|---|---|---|---|
| Benannte Gruppe | (?<name>…) | (?P<name>…) | beide Formen |
| \d und \w | nur ASCII | standardmäßig Unicode | ASCII, außer mit UCP |
| Possessive Quantoren und atomare Gruppen (a++, (?>…)) | nein | ja, seit Python 3.11 | ja |
| Inline-Flags wie (?i) | nur die begrenzte Form (?i:…), seit ECMAScript 2025 | ja | ja |
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
- MDN Web Docs — Regular expressions (JavaScript guide)
- MDN Web Docs — Regular expression syntax cheat sheet
- ECMAScript® Language Specification — RegExp (Regular Expression) Objects
- TC39 — Finished proposals (RegExp modifiers and duplicate named groups: ECMAScript 2025)
- Python documentation — re: regular expression operations
- PCRE2 — pcre2pattern: syntax and semantics of the regular expressions
- OWASP — Regular expression Denial of Service (ReDoS)
- WHATWG HTML Standard — Valid email address
- RFC 5322 — Internet Message Format (October 2008)
Weitere Ratgeber
- IP-Adressen erklärt: IPv4, IPv6 und die reservierten Bereiche
- Subnetze und CIDR erklärt: Präfixe, Masken und nutzbare Hosts
- DNS-Einträge erklärt: A, AAAA, CNAME, MX, TXT und NS
- Ist eine Website down oder liegt es an Ihnen? So prüfen Sie es Schritt für Schritt
- HTTP-Statuscodes und Cloudflare-Fehler: was 403, 404, 429, 500, 503 und 521 bedeuten
- Unix-Zeitstempel und Zeitzonen erklärt
- Mit Datumsangaben rechnen: Tage zwischen zwei Daten, Schaltjahre und ISO-Wochen
- Zeitzonen und Sommerzeit: Termine über Städte hinweg
- Bildformate erklärt: JPEG, PNG, WebP, AVIF und HEIC
- Bildgröße erklärt: Pixel, DPI, Dateigröße und Qualität
- Handyfotos erklärt: HEIC, EXIF-Metadaten und Ihre Privatsphäre
- Passwortstärke erklärt: Länge, Entropie und Passphrasen
- Hashfunktionen erklärt: SHA-256, Prüfsummen und Passwort-Hashing
- JSON Web Tokens erklärt: Claims, Signaturen und sichere Prüfung
- API-Schlüssel erklärt: Länge, Format, Speicherung und Rotation
- UUIDs erklärt: v4, v7 und die Wahl der richtigen Version
- QR-Codes erklärt: Kapazität, Fehlerkorrektur und Druckgröße
- Prozente und Mehrwertsteuer erklärt: aufschlagen, herausrechnen, kombinieren
- Häufige JSON-Fehler und wie man sie behebt
- CSV-Dateien erklärt: Trennzeichen, Anführungszeichen, Kodierung und Excel
- Textkodierungen erklärt: UTF-8, Base64 und URL-Kodierung
- PDFs im Browser bearbeiten: Was beim Zusammenfügen, Teilen und Umwandeln erhalten bleibt