The exponential trap
Some innocent-looking regex patterns become exponentially slow on certain inputs. The pattern (a+)+b matches 'aaaab' instantly. Run it against 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaa' (no 'b' at the end) and your CPU spins for minutes or hangs forever.
Why this happens
The engine tries every possible way to split the input among the iterations of a+. With 30 a's, that's 2^30 (~1 billion) splits. Each split fails because there's no 'b'. The engine tries them all before giving up.
The danger pattern
Look for nested quantifiers where the inner and outer can both match the same characters:
(a+)+— inner and outer both match a's(a*)*— same(a|a)+— alternatives match the same thing(a|b)*c— when the input lacks c, every char can be tried as a or b(\w+\s)+— when the input ends without space
Anywhere a quantifier-bearing piece can be split multiple ways AND the rest of the pattern fails, you have potential explosion.
Fixes
- Atomic groups / possessive quantifiers — disable backtracking.
(?>a+)+bora++b. - Negated character classes —
[^X]+can't backtrack to find X.[^"]*instead of.*?. - Anchoring —
^pattern$at least limits the engine to one position. - Use RE2/Go for adversarial input — RE2 doesn't backtrack; impossible to ReDoS.