tooloora

Regex-Tester – Treffer, Gruppen und Ersetzen, ohne eingefrorenen Tab

Muster eintippen, jeden Treffer hervorgehoben sehen, mit nummerierten und benannten Gruppen, dazu die Ersetzen-Vorschau. Die Auswertung läuft in einem Web Worker mit harter Zeitgrenze: Ein entgleistes Muster wird abgebrochen, statt den Browser zu blockieren.

Läuft lokal – nichts wird hochgeladen

g
Muster-Bibliothek

Ein Klick lädt Muster, Schalter und einen Beispieltext. Die Muster sind Startpunkte zum Ausprobieren, keine Prüfregeln: Ein Treffer heißt nur, dass die Form stimmt.

$1 bis $99 setzen nummerierte Gruppen ein, $<name> benannte Gruppen, $& den ganzen Treffer, $$ ein Dollarzeichen.

Bestandteile des Musters

Sobald oben ein Muster steht, wird es hier Stück für Stück erklärt.

Warum ein eigener Rechenthread?

Ein Muster wie (a+)+b braucht auf 30 Zeichen Milliarden Rückschritte, und ein laufender regulärer Ausdruck lässt sich von innen nicht abbrechen. Deshalb läuft deine Eingabe in einem Web Worker: Antwortet er nicht rechtzeitig, wird er von außen beendet und die Seite bleibt bedienbar.

Grenzen

Ausgewertet werden bis zu 100.000 Zeichen Testtext und 1.000 Treffer. Nach 1 Sekunde Rechenzeit gibt die Suche auf.

Läuft lokal in deinem Browser – Muster und Testtext werden nirgendwohin gesendet.

Reguläre Ausdrücke testen, ohne den Tab zu riskieren

Muster oben eintippen, Testtext einfügen, Treffer sofort hervorgehoben sehen: mit nummerierten und benannten Gruppen je Treffer, einer Ersetzen-Vorschau für $1 und $<name> und einer Erklärung jedes Bestandteils. Die Auswertung läuft in deinem Browser, in einem eigenen Rechenthread mit harter Zeitgrenze. Kein Upload, keine Anmeldung.

Warum friert ein Regex-Tester überhaupt ein?

Weil ein laufender regulärer Ausdruck sich in JavaScript nicht abbrechen lässt. Das Muster (a+)+b sieht harmlos aus, zwingt die Engine auf 30 Zeichen aber zu Milliarden von Rückschritten, weil sie jede mögliche Aufteilung der a durchprobiert, bevor sie aufgibt. Solange sie rechnet, steht der ganze Thread: kein Klick, kein Scrollen, keine Fehlermeldung.

Der Fachbegriff dafür ist ReDoS (Regular Expression Denial of Service), und er ist keine Laborkuriosität. Am 2. Juli 2019 brachte ein einziger regulärer Ausdruck mit katastrophalem Backtracking in einer neuen Firewall-Regel das weltweite Netz von Cloudflare für 27 Minuten zum Erliegen; das Unternehmen hat den Vorfall selbst ausführlich dokumentiert. Wenn ein solches Muster ein Rechenzentrum lahmlegen kann, legt es einen Browser-Tab erst recht lahm.

Deshalb ist dieses Werkzeug so gebaut: Dein Muster läuft in einem Web Worker, also einem eigenen Thread. Der Haupt-Thread stellt gleichzeitig einen Wecker. Antwortet der Worker nicht rechtzeitig, wird er von außen beendet und für die nächste Anfrage ein frischer gestartet. Von innen wäre das unmöglich, und genau darin liegt der Unterschied zu einem Tester, der Fremdmuster einfach im Haupt-Thread ausführt.

Wie liest man Gruppen richtig?

Jede runde Klammer im Muster merkt sich, was sie getroffen hat. (\d{4}) ist Gruppe 1, die nächste Klammer Gruppe 2 und so weiter. Übersichtlicher wird es mit benannten Gruppen: (?<jahr>\d{4}) trägt ihren Zweck im Namen und überlebt jede spätere Umsortierung des Musters. Braucht eine Klammer nur die Gruppierung, aber kein Gedächtnis, schreibt man (?:…); das spart Arbeit und hält die Nummerierung sauber.

Die Trefferliste zeigt beides nebeneinander. Wichtig ist die Unterscheidung zwischen nicht beteiligt und leer: In (a)|(b) bleibt bei einem Treffer auf b die erste Gruppe unbeteiligt, sie hat also keinen Wert. Eine Gruppe wie (x*) kann dagegen sehr wohl beteiligt sein und trotzdem leeren Text enthalten. Wer das verwechselt, baut sich beim Ersetzen still falsche Ergebnisse.

Was tun $1 und $<name> beim Ersetzen?

Im Ersetzen-Feld gelten dieselben Regeln wie bei String.prototype.replace:

  • $1 bis $99 setzen den Inhalt der nummerierten Gruppe ein
  • $<name> den Inhalt der benannten Gruppe
  • $& den ganzen Treffer, $` den Text davor, $' den danach
  • $$ ein einzelnes Dollarzeichen

Aus 24.12.2026 wird mit der Vorlage $<jahr>-$<monat>-$<tag> also 2026-12-24. Die Vorschau rechnet dabei auf den bereits gefundenen Treffern, führt das Muster also kein zweites Mal aus. Das ist kein Detail: Ein zweiter Lauf im Haupt-Thread wäre genau die Stelle, an der die Seite doch noch einfriert.

Warum gibt es keine perfekte E-Mail-Regex?

RFC 5322 erlaubt zitierte Bestandteile, Kommentare in Klammern und verschachtelte Konstrukte. Ein vollständig konformer Ausdruck ist deshalb tausende Zeichen lang, kaum lesbar und sagt trotzdem nichts darüber aus, ob hinter der Adresse ein Postfach steht. Der HTML-Standard löst das Problem, indem er ein eigenes, bewusst einfacheres Muster für input type="email" festlegt und diese Vereinfachung ausdrücklich als absichtliche Abweichung von RFC 5322 bezeichnet.

Das Muster in der Bibliothek folgt derselben Linie: Es fängt Tippfehler ab, mehr verspricht es nicht. Wer Adressen wirklich prüfen will, verschickt eine Bestätigungsmail; alles andere ist Kosmetik. Genauso bei der IBAN: Die Länge ist je Land verschieden (nach ISO 13616 zwischen 15 und 34 Zeichen, in Deutschland 22), und die eigentliche Prüfziffer ist eine Modulo-97-Rechnung, die kein regulärer Ausdruck leisten kann. Ein Muster prüft die Form, nie den Inhalt.

Wo unterscheiden sich Muster zwischen Browsern?

Benannte Gruppen und die Rückschau (?<=…) kamen mit ES2018 in die Sprache, aber nicht überall gleichzeitig an: Safari unterstützt die Rückschau erst ab Version 16.4 (März 2023). Ein Muster, das in Chrome sauber läuft, kann auf einem älteren iPhone einen Syntaxfehler auslösen. Wenn dein Ausdruck später im Browser eines Kunden landen soll, lohnt sich hier ein Blick, bevor er in den Code wandert.

Ehrliche Grenzen

Ausgewertet werden bis zu 100.000 Zeichen Testtext und 1.000 Treffer; der Worker gibt nach einer Sekunde Rechenzeit auf, der Wecker im Haupt-Thread nach 2,5 Sekunden. Die Trefferliste zeigt die ersten 100 Einträge ausführlich, hervorgehoben werden weiterhin alle. Für ganze Logdateien ist ein Kommandozeilen-Werkzeug wie ripgrep das passendere Instrument. Und für die häufigste Falle gibt es keine Grenze, sondern nur Aufmerksamkeit: Verschachtelte Wiederholungen wie (a+)+ oder (\w+\s?)* sind der Bauplan für ein Muster, das im Ernstfall nicht mehr zurückkommt.

Häufige Fragen

Warum läuft die Auswertung in einem Web Worker?

Weil sich ein regulärer Ausdruck von innen nicht abbrechen lässt. Ein Muster wie (a+)+b braucht auf 30 Zeichen Milliarden Rückschritte, und solange die Engine rechnet, läuft in diesem Thread nichts anderes. Im Haupt-Thread heißt das: eingefrorener Tab. Hier läuft jedes Muster in einem eigenen Worker mit harter Zeitgrenze; ist sie erreicht, wird der Thread beendet und ein frischer gestartet. Das Problem heißt ReDoS und ist keine Theorie: Am 2. Juli 2019 legte ein einziger regulärer Ausdruck mit katastrophalem Backtracking das weltweite Netz von Cloudflare für 27 Minuten lahm.

Wird mein Testtext irgendwohin hochgeladen?

Nein. Muster, Schalter und Text bleiben im Browser; der Worker ist ein lokales Skript von dieser Seite, und es gibt keine Anfrage, die deine Daten mitnimmt. Das ist wichtiger als es klingt, denn Testtext ist oft Echtdaten: Log-Ausschnitte, Kundendatensätze, Zugangsschlüssel. Nachprüfen kannst du es im Netzwerk-Tab der Entwicklerwerkzeuge.

Gibt es die perfekte Regex für E-Mail-Adressen?

Nein, und wer eine anbietet, vereinfacht. RFC 5322 erlaubt zitierte Bestandteile, Kommentare und Verschachtelung; ein vollständig konformer Ausdruck ist tausende Zeichen lang und sagt trotzdem nicht, ob ein Postfach existiert. Der HTML-Standard umgeht das, indem er ein eigenes, bewusst einfacheres Muster festlegt und es ausdrücklich als absichtliche Abweichung von RFC 5322 bezeichnet. Das Muster in unserer Bibliothek folgt derselben pragmatischen Linie: Es fängt Tippfehler ab, es ist keine Gültigkeitsprüfung. Die einzige echte Prüfung ist eine Bestätigungsmail.

Was bewirken $1 und $<name> im Ersetzen-Feld?

Sie setzen ein, was eine Gruppe getroffen hat. $1 meint die erste nummerierte Gruppe, $<name> eine Gruppe, die als (?<name>...) geschrieben wurde. Dazu setzt $& den ganzen Treffer ein und $$ ein einzelnes Dollarzeichen. Die Vorschau wendet genau diese Regeln auf die bereits gefundenen Treffer an, wie es String.prototype.replace täte; das Muster wird also kein zweites Mal ausgeführt.

Welche Schalter gibt es und was ändern sie?

g findet alle Treffer statt nur den ersten, i ignoriert Groß- und Kleinschreibung, m lässt ^ und $ auch an Zeilenumbrüchen greifen, s lässt den Punkt auch Zeilenumbrüche treffen, u schaltet den vollen Unicode-Modus ein, und y (sticky) verlangt, dass jeder Treffer genau dort beginnt, wo der vorige endete. Beachte: Die Rückschau (?<=...) kam in Safari spät und funktioniert erst ab Safari 16.4. Ein Muster, das in Chrome läuft, kann auf älteren iPhones also scheitern.

Gibt es Grenzen?

Ja, und sie werden offen genannt: Ausgewertet werden bis zu 100.000 Zeichen Testtext und bis zu 1.000 Treffer, der Worker gibt nach einer Sekunde Rechenzeit auf, und der Haupt-Thread beendet einen schweigenden Worker nach 2,5 Sekunden. Die Trefferliste zeigt die ersten 100 Einträge ausführlich, hervorgehoben werden weiterhin alle. Für größere Mengen ist ein Kommandozeilen-Werkzeug wie ripgrep das bessere Instrument.