Regex Explainer

Catastrophic backtracking, minimal example

The smallest pattern that exhibits exponential backtracking. Three characters longer than the safe version and indistinguishable by eye.

/^(a+)+$/

Match a whole string consisting of one or more of (one or more of "a").

Do not run this against untrusted input — see below.

What to check

  • Dangerous

    Catastrophic backtracking — this pattern can hang

    (a+)+

    A quantifier repeats a group that itself contains an unbounded quantifier over an overlapping character set. On input that ALMOST matches, the engine has exponentially many ways to split the text between the two quantifiers and must try all of them before it can report failure. A few dozen characters can take minutes of CPU, which makes this a denial-of-service vector if the pattern ever runs against untrusted input.

    Fix: Remove one level of repetition. Usually the inner quantifier alone is enough: (a+)+ means the same thing as a+. Where the nesting is genuinely needed, make the inner part non-overlapping or use an atomic group in an engine that has one — JavaScript does not.

  • Note

    Anchors match string ends, not line ends

    Without the m flag, ^ and $ match only the very start and end of the input — not the start and end of each line. On multi-line input this is often not what was intended.

    Fix: Add the m flag if the pattern should apply per line.

Step by step

  1. ^

    Anchor to the start of the input.

  2. (a+)+

    Match one or more of (one or more of "a").

  3. $

    Anchor to the end of the input.

Details

Capture groups
1
Flags
None set

Check your own pattern

Paste one on the home page, or call the API or MCP server. This page is also available as markdown.

Related examples