Regex-Tester
Schreibe ein Muster, sieh zu, wie es beim Tippen deinen Text matcht, und erfahre genau, was jedes Token tut. Capture-Gruppen, eine Ersetzungsvorschau und eine Kompatibilitätsprüfung für PCRE und Python.
Muster
Dein regulärer Ausdruck
Schreibe nur den Musterkörper — ohne umgebende Schrägstriche. Alles aktualisiert sich beim Tippen.
Ändert nur die Kompatibilitätsprüfung — der Abgleich läuft immer auf der JavaScript-Engine deines Browsers.
Presets
Testtext
Text zum Abgleichen
Füge echte Daten ein — eine Log-Zeile, eine Config, einen Chat-Export. Nichts verlässt deinen Browser.
794 Zeichen · 14 Zeilen
Wespner ops log — node eu-fra-03 Ticket #4821 opened by [email protected], escalated to [email protected]. Billing contact: [email protected] (invoice WX-2026-0917). Panel: https://panel.wespner.eu/server/eu-fra-03/console Mirror: http://mirror.wespner.eu:8080/backups/latest.tar.zst Node IP 185.199.110.153, gateway 10.0.0.1, bad entry 999.1.1.1 in the allowlist. Server UUID 9f2c1a7e-3b44-4d8e-9c21-7a5f0b6e2d13 (instance 550e8400-e29b-41d4-a716-446655440000). Chat export: [12:04] Steve_84: this build is hell to maintain, honestly [12:05] Alex_MC: rotate the panel password and open a shell on the class-4 node [12:06] Steve_84: damn, the ass-end of that config is unreadable [12:07] Notch_Fan: <img src=x onerror=alert(1)> nice try [12:08] Alex_MC: harassment report filed, see /docs/rcon
Capture-Gruppen
Jeder Treffer, mit Gruppen und Positionen
Nummerierte Gruppen stammen von einfachem ( ). Benannte Gruppen stammen von (?<name>…) und werden separat aufgeführt.
Gib ein Muster ein, um Treffer und ihre Capture-Gruppen zu sehen.
Erklärungsmodus
Was jeder Teil des Musters tatsächlich tut
Von oben nach unten lesen — so liest die Engine es auch. Die Einrückung zeigt die Verschachtelung innerhalb von Gruppen.
(?<user>Named capturing group “user”, also group number 1. Refer to it as $<user> in a replacement, or \k<user> in the pattern.[\w.+-]Any single character that is a word character (letter, digit or underscore), “.”, “+” or “-”.+Repeats the previous token one or more times. Greedy: it takes as much as it can, then hands characters back one at a time if the rest of the pattern fails.)Closes the group opened above.@The character “@”, matched literally.(?<domain>Named capturing group “domain”, also group number 2. Refer to it as $<domain> in a replacement, or \k<domain> in the pattern.(?:Non-capturing group: groups tokens together for a quantifier or an alternation without storing what it matched, so it does not consume a group number.[\w-]Any single character that is a word character (letter, digit or underscore) or “-”.+Repeats the previous token one or more times. Greedy: it takes as much as it can, then hands characters back one at a time if the rest of the pattern fails.\.The character “.”, matched literally. The backslash strips any special meaning it would otherwise have.)Closes the group opened above.+Repeats the previous token one or more times. Greedy: it takes as much as it can, then hands characters back one at a time if the rest of the pattern fails.[a-z]Any single character that is anything from “a” to “z”.{2,}Repeats the previous token at least 2 times, with no upper limit. Greedy: it takes as much as it can, then hands characters back one at a time if the rest of the pattern fails.)Closes the group opened above.giFlags: g finds every match instead of stopping at the first; i ignores letter case.Ersetzen
Suchen-und-Ersetzen-Vorschau
Nutze $1, $2 für nummerierte Gruppen, $<name> für benannte, $& für den gesamten Treffer und $$ für ein literales Dollarzeichen.
Ergebnis
Gib ein Muster ein, um eine Ersetzungsvorschau zu sehen.
Ehrlicher Hinweis
Diese Seite führt kein PCRE oder Python aus
Hier gibt es nur eine Regex-Engine: die in deinem Browser eingebaute, die JavaScripts Dialekt implementiert. PCRE oder Python auszuwählen wechselt nicht die Engine und kann es auch nicht — in diesem Tab läuft weder PCRE noch CPython.
Was die Dialekt-Einstellung stattdessen tut: Sie prüft dein Muster auf Konstrukte, die im gewählten Dialekt anders geschrieben werden, sich anders verhalten oder schlicht nicht existieren. Behandle die Treffer oben als JavaScript-Ergebnisse und die Liste rechts als „was dich beißt, wenn du das in PHP oder Python einfügst“.
Entsprechender Aufruf
const re = /(?<user>[\w.+-]+)@(?<domain>(?:[\w-]+\.)+[a-z]{2,})/gi;
for (const m of text.matchAll(re)) console.log(m);A literal is fine when the pattern is fixed. Building one from a variable needs new RegExp(src, flags) — and the source escaped first.
Kompatibilitätsprüfung
Kompatibilität mit JavaScript
Heuristisch — das Muster wird als Text gescannt, daher kann ein Konstrukt, das innerhalb einer Zeichenklasse steht, trotzdem gemeldet werden.
Cheat Sheet
Greedy vs. lazy
Der mit Abstand häufigste Grund, warum ein Muster „zu viel matcht“.
<.*> gegen <b>bold</b> matcht den gesamten String, nicht <b>. * und + sind gierig (greedy): Sie schnappen sich alles, was sie können, und geben Zeichen nur zurück, wenn der Rest des Musters sonst scheitert.
Füge ? hinzu, um einen Quantor faul (lazy) zu machen — <.*?> stoppt beim ersten >. Meist noch besser: sag, was du wirklich meinst, <[^>]*>, das den Trenner gar nicht überschreiten kann und nicht zurückverfolgt.
Cheat Sheet
Anker und Grenzen
^ und $ stehen für Anfang und Ende des Strings — bis du das m-Flag hinzufügst, dann werden sie zu Anfang und Ende jeder Zeile. Wird m bei einer mehrzeiligen Config-Datei vergessen, matcht ein zeilenweises Muster stillschweigend gar nichts.
\b ist eine Wortgrenze mit Länge null, kein Zeichen. \bcat\b matcht cat, aber nicht concatenate. Innerhalb einer Zeichenklasse bedeutet [\b] dagegen Backspace — eine echte Falle.
Ein Muster, das die gesamte Eingabe matchen muss, braucht beide Anker. ^\d+ allein matcht bereitwillig den Anfang von 123abc.
Cheat Sheet
Katastrophales Backtracking
Verschachtelte Quantoren, bei denen der innere und äußere Teil denselben Text matchen können — (a+)+$, (\w+\s?)*$, (\d+)*x — geben der Engine exponentiell viele Möglichkeiten, die Eingabe aufzuteilen. Bei einem nicht passenden String verdoppelt grob jedes zusätzliche Zeichen den Aufwand, sodass 30 Zeichen Minuten dauern können.
Die Lösung ist, die Mehrdeutigkeit zu entfernen: aus (a+)+ wird a+; aus (\w+\s?)* wird \w+(?:\s\w+)*. Wo deine Engine es unterstützt, verbietet eine atomare Gruppe (?>…) oder ein besitzergreifender Quantor a++ das Backtracking von vornherein — PCRE und Python 3.11+ haben beide, JavaScript keines von beiden.
Dieser Tester führt den Abgleich in einem Web Worker mit Zeitlimit aus, sodass ein außer Kontrolle geratenes Muster abgebrochen wird, statt den Tab einzufrieren. Dein Produktivserver hat kein solches Sicherheitsnetz.
Cheat Sheet
Wortfilter und das Scunthorpe-Problem
Eine Wortliste ohne Grenzen matcht auch innerhalb unschuldiger Wörter. Der klassische Fall ist die englische Stadt Scunthorpe, deren Einwohner sich jahrelang wegen der vier Buchstaben in der Mitte ihres Namens nicht für Dienste anmelden konnten.
Näher dran: hell matcht shell, ass matcht class und password, doc matcht document. \b(?:…)\b um die Alternation herum behebt das meiste davon. Absichtliche Umgehung (h e l l, h3ll) wird dadurch nicht behoben, und dem mit Regex hinterherzujagen erzeugt mehr Fehlalarme, als es verhindert — deshalb kombiniert echte Moderation eine kleine, konservative Regex mit menschlicher Prüfung.
Cheat Sheet
Escaping, Klassen und der Punkt
Innerhalb von [ ] verlieren die meisten Metazeichen ihre Bedeutung: [.+*] sind drei literale Zeichen. Nur ^ (an erster Stelle), - (zwischen Zeichen) und der Backslash bleiben besonders, und ] muss escaped werden.
Der Punkt bedeutet „jedes Zeichen außer einem Zeilenumbruch“, bis du s hinzufügst. In einem IP- oder Versionsmuster matcht ein nicht escapter Punkt alles — 1.2.3.4 matcht auch 1x2y3z4.
Baust du ein Muster aus Benutzereingaben, escape sie zuerst. In JavaScript: s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"). In PHP preg_quote(), in Python re.escape().
Cheat Sheet
Gruppen, die du wahrscheinlich nicht capturen willst
Jede ( ) speichert ihren Treffer und nummeriert alles danach neu. Brauchst du die Gruppierung nur für eine Alternation oder einen Quantor, nutze (?:…) — so bleibt dein $1 stabil, wenn du später davor eine Gruppe hinzufügst.
Benannte Gruppen (?<user>…) überstehen Umordnungen vollständig und lesen sich in einem Ersetzungsstring viel besser: $<user> statt $3. Python schreibt sie als (?P<user>…).
Betreibst du einen eigenen Gameserver?
Wespner-Gameserver mit DDoS-Schutz, NVMe-Laufwerken und Aktivierung innerhalb von Minuten.