Was passiert eigentlich, wenn ein Regex-Muster "hängt"?
KurzantwortEine Regex-Engine probiert bei einem nicht eindeutigen Muster unter Umständen sehr viele verschiedene Wege aus, den Text zu zerlegen, bevor sie aufgibt. Bei einem mehrdeutigen Muster wie (a+)+b kann die Anzahl dieser Versuche mit jedem zusätzlichen Zeichen im Eingabetext explosionsartig wachsen — man spricht von katastrophalem Backtracking. Das Ergebnis: Ein Muster, das bei fünf Zeichen sofort antwortet, kann bei fünfundzwanzig Zeichen spürbar hängen und bei fünfzig praktisch nie mehr fertig werden.
Das Tückische daran ist, dass das Muster selbst dabei völlig korrekt aussieht und in den meisten Alltagstests unauffällig bleibt — solange der Testtext kurz ist oder tatsächlich passt. Das Problem zeigt sich typischerweise erst bei längeren Zeichenketten, die dem Muster ähneln, aber am Ende NICHT passen, weil die Engine dann jede denkbare Aufteilung durchprobiert, bevor sie endgültig "kein Treffer" meldet.
Gut zu wissen: Das ist kein Bug in einer bestimmten Regex-Engine, sondern eine grundsätzliche Eigenschaft, wie Backtracking-basierte Engines (darunter die in JavaScript, PHP, Python und Java eingebauten) funktionieren. ECMAScript, PCRE und Javas Regex-Engine sind davon alle gleichermaßen betroffen, wenn das Muster entsprechend mehrdeutig aufgebaut ist.
Welche Musterformen sind typischerweise verdächtig?
KurzantwortAm häufigsten entsteht das Problem durch eine Wiederholung innerhalb einer anderen Wiederholung, bei der beide dieselben oder überlappenden Zeichen zulassen — zum Beispiel (a+)+, (a*)* oder (a|ab)*. Auch lange Ketten optionaler Gruppen wie (a?){15}a{15} gelten als klassische Lehrbuchbeispiele.
- Verschachtelte Quantoren mit Überlappung —
(a+)+: die äußere und innere Wiederholung können denselben Text auf viele Arten unter sich aufteilen.
- Alternation mit Überlappung —
(a|a)* oder (a|ab)*: mehrere Alternativen, die auf dieselbe Eingabe passen, vervielfachen die möglichen Lesarten.
- Lange Ketten optionaler Gruppen —
(x?){n}x{n}: mit wachsendem n steigt die Anzahl möglicher Kombinationen sehr schnell.
- Unproblematisch zum Vergleich — ein einzelner Quantor wie
a+, \d{3,10} oder eine nicht verschachtelte Gruppe wie (?:abc)+ verursacht in aller Regel keine derartigen Probleme.
Diese Formen händisch zu erkennen ist eine nützliche Fähigkeit, gerade wenn du Muster aus fremden Quellen (einer alten Codebasis, einem Forumsbeitrag oder einer KI-Antwort) unverändert übernimmst, statt sie selbst von Grund auf zu schreiben. Der ToolPico Regex-Tester zeigt aktuell keine automatische Warnung für solche Formmuster an — eine kleine Zeitanzeige neben der Trefferzahl (etwa "Ausgeführt in 4 ms"), kombiniert mit einer einfachen Heuristik, die klassische verschachtelte Quantoren wie (a+)+ erkennt und markiert, ist eine denkbare künftige Ergänzung des Tools. Bis dahin hilft die manuelle Methode im nächsten Abschnitt.
Wie testet man ein verdächtiges Muster, ohne die Seite lahmzulegen?
KurzantwortBeginne mit einem sehr kurzen Testtext und verlängere ihn erst schrittweise. Bleibt die Reaktion bei jeder Verdopplung der Textlänge etwa gleich schnell, ist das Muster wahrscheinlich unbedenklich; verlangsamt sie sich dagegen spürbar, deutet das auf katastrophales Backtracking hin.
Ein praktisches Vorgehen im Reiter „Treffer” des Regex-Testers: Trage zunächst eine kurze, nicht passende Zeichenkette ein (angenommen 10 Zeichen einer Wiederholung, gefolgt von einem Zeichen, das das Muster am Ende NICHT erfüllt) und beobachte, wie schnell das Ergebnis erscheint. Verlängere die Wiederholung anschließend auf 15, dann 20 Zeichen. Bei einem unproblematischen Muster bleibt die gefühlte Reaktionszeit nahezu konstant. Bei einem Muster mit verschachtelten Quantoren dagegen kann bereits der Sprung von 20 auf 25 Zeichen den Unterschied zwischen einer sofortigen Antwort und einem spürbar zähen Browser-Tab ausmachen — in einem solchen Fall lohnt es sich, das Muster umzuschreiben, etwa durch Entfernen der äußeren Wiederholung oder durch eine nicht-erfassende Gruppe ohne doppelte Wiederholung.
Beispiel (illustrativ): Angenommen, ein Muster mit verschachtelter Wiederholung reagiert bei einer 15 Zeichen langen nicht-passenden Testzeile noch spürbar schnell, bei 25 Zeichen bereits merklich langsamer und bei 35 Zeichen deutlich zäh — ein solches Verlaufsmuster (schnell → langsam → sehr langsam bei linear wachsender Textlänge) ist ein typisches Warnzeichen für katastrophales Backtracking. Die genauen Werte hängen immer vom jeweiligen Muster, Gerät und Browser ab und dienen hier nur der Veranschaulichung.
| Musterform | Risiko | Warum |
| a+ | Gering | Einzelne Wiederholung, keine Verschachtelung |
| (?:abc)+ | Gering | Nicht-erfassende Gruppe, keine überlappende innere Wiederholung |
| (a+)+ | Hoch | Verschachtelte Wiederholung mit vollständiger Überlappung |
| (a|a)* | Hoch | Zwei identische Alternativen in einer Wiederholung |
Nützlich ist außerdem der Reiter „Erklären” des Regex-Testers: Er zerlegt dein Muster Stück für Stück, sodass du verschachtelte Gruppen und Wiederholungen leichter isoliert betrachten kannst, statt das gesamte Muster auf einen Blick entschlüsseln zu müssen. Sobald du dir sicher bist, dass das Muster stabil läuft, kannst du im Reiter „Code generieren” den passenden JavaScript-, Python-, PHP- oder Java-Code dafür übernehmen.
Häufig gestellte Fragen
Was ist katastrophales Backtracking bei Regex?
Katastrophales Backtracking (auf Englisch catastrophic backtracking oder ReDoS) tritt auf, wenn eine Regex-Engine bei einem nicht passenden Text extrem viele Kombinationen ausprobiert, weil das Muster mehrdeutig ist — typischerweise durch verschachtelte Wiederholungen wie (a+)+. Die Laufzeit kann dabei mit jedem zusätzlichen Zeichen im Eingabetext exponentiell statt linear wachsen, sodass ein an sich winziges Muster bei ungünstigem Text den Browser oder Server für Sekunden bis Minuten blockiert.
Woran erkennt man ein riskantes Regex-Muster mit bloßem Auge?
Ein typisches Warnzeichen ist eine Wiederholung innerhalb einer Wiederholung, bei der beide dieselben oder überlappende Zeichen erlauben — etwa (a+)+, (a*)* oder (a|a)*. Auch mehrere aufeinanderfolgende optionale Gruppen wie (a?){20} oder eine Kombination aus .* mit anschließendem festen Text am Ende eines langen Musters können in bestimmten Engines zu spürbaren Verzögerungen führen. Eine einzelne Wiederholung wie a+ oder (?:abc)+ ohne verschachtelte Wiederholung ist dagegen in aller Regel unproblematisch.
Wie testet man ein verdächtiges Muster, ohne die Seite einzufrieren?
Teste zunächst mit einem kurzen Text (wenige Zeichen) statt mit einem langen Textblock, und beobachte, ob das Ergebnis sofort erscheint. Verlängere den Testtext danach schrittweise, zum Beispiel von 10 auf 20 und dann 30 gleiche Zeichen ohne abschließenden Treffer. Bleibt die Reaktion bei jeder Verdopplung der Länge etwa gleich schnell, ist das Muster wahrscheinlich unproblematisch; verlangsamt sie sich dagegen merklich mit jedem zusätzlichen Zeichen, liegt vermutlich katastrophales Backtracking vor und das Muster sollte überarbeitet werden, bevor es in Produktion läuft.
Warum zeigt der Regex-Tester selbst keine Laufzeit oder Warnung für langsame Muster an?
Der ToolPico Regex-Tester zeigt aktuell Trefferanzahl, Position und Gruppen, jedoch keine gemessene Ausführungszeit und keine automatische Heuristik-Warnung für riskante Musterformen wie verschachtelte Quantoren. Eine kleine Anzeige „Ausgeführt in X ms” neben der Trefferzahl, ergänzt um eine einfache Formmustererkennung für klassische Risikokandidaten, ist eine denkbare künftige Ergänzung — bis dahin hilft die manuelle Schritt-für-Schritt-Testmethode aus diesem Artikel.
Sollte man verschachtelte Quantoren in Regex grundsätzlich vermeiden?
Nicht jede verschachtelte Wiederholung ist gefährlich — problematisch wird es vor allem, wenn die innere und äußere Wiederholung sich in ihrer Zeichenmenge überschneiden, sodass derselbe Textabschnitt auf viele verschiedene Arten aufgeteilt werden kann. Lässt sich dieselbe Absicht mit einer einzigen, nicht verschachtelten Wiederholung ausdrücken (zum Beispiel a+ statt (a+)+), ist das in der Regel vorzuziehen — sowohl für die Lesbarkeit als auch für die Ausführungsgeschwindigkeit.