Regex Tester With Backtracking Warning
Test a pattern against your own text with a step budget, and find out before production whether it can be made to backtrack catastrophically.
Everything on this page runs in your browser. Nothing you paste is uploaded, logged, or written into the URL — only the settings are, so a configured tool can still be linked to. The pattern, the flags and the budget are settings and do travel in the link; the subject you test against does not.
The budget of 200,000 steps was exhausted without an answer. Your browser's engine was never handed this pattern.
| subject length | steps | result |
|---|---|---|
| 4 characters | 89 | no match |
| 6 characters | 163 | no match |
| 9 characters | 782 | no match |
| 14 characters | 6,867 | no match |
| 21 characters | 138,458 | no match |
| 32 characters | over 200,001 | gave up |
| 44 characters | over 200,001 | gave up |
The same pattern against the first N characters of your subject, with its final character kept on the end so a rejecting case stays a rejecting case. Steps roughly doubling for a handful of extra characters is catastrophic backtracking; steps growing in step with the length is a healthy pattern.
- errorpattern offset 9a quantifier wrapped around something that is itself quantified — the (a+)+ shape. The number of ways to divide a run of matching characters between the inner and outer repeats is exponential in the length of that run, so a subject that ALMOST matches takes exponential time to reject
Expected: a single quantifier over the repeated unit — (a+) or a+ — or an inner unit that cannot match what the outer one can. This is the shape behind essentially every published regular-expression denial of service
^(\w+\s?)*$ - error200,001 stepsthe match was abandoned at the step budget. Nothing was handed to your browser's engine, because a search this large is exactly the one that would not come back
Expected: a pattern that resolves within the budget. Raise the budget to see how far it gets, or read the growth table below — if the steps double for every character added, no budget is large enough
- errorthe step count grows as roughly length^0.0 across the last two rows of the growth table — steeper than quadratic, which is the signature of exponential backtracking rather than a merely slow pattern
Expected: steps growing about linearly with the subject. Adding ten characters should cost ten times one character, not a thousand times
\p escapes or the u, v, y and d flags; a pattern using any of them is reported and not executed at all, rather than analysed by halves. And a clean report is not a proof: this checks the shapes that are known to explode, not every pattern that could.Why the failing case is the expensive one
A regular expression that matches usually stops at the first success. One that fails has to prove no arrangement works, and in a backtracking engine that means trying every arrangement. Wrap a quantifier around something already quantified and the number of arrangements doubles for each extra character: (a+)+$ against thirty a's and an exclamation mark is a billion attempts. That is the whole attack. An input field, a log line or a filename that a user controls, matched against a pattern with this shape, is a single request that pins a CPU core for minutes.
What to do when the warning fires
Almost every nested quantifier is an accident of writing rather than an intent. (\w+\s?)* was meant to say "words separated by optional spaces", and \w+(\s\w+)* says the same thing with no ambiguity at all, because a space is the only way into the repeat. The general fix is to make each repetition start with something only it can consume. Where the pattern genuinely has to be ambiguous, or where it comes from a user, the answer is not a cleverer pattern: it is a length cap on the input, a regular-expression engine with a linear guarantee, or moving the work off the request thread. Timeouts do not help — there is nothing to interrupt.