Atomic Groups and Possessive Quantifiers
Atomic groups (?>...) and possessive quantifiers (a++, a*+) stop the engine from backtracking into a match — the main cure for catastrophic backtracking. Java and PCRE support them; JavaScript and Go do not.
Support at a glance
| Engine | Atomic (?>...) | Possessive a++ |
|---|---|---|
| Java | Yes | Yes |
| PHP / PCRE | Yes | Yes |
Python re (3.11+) | Yes | Yes |
Python regex module | Yes | Yes |
| JavaScript | No | No |
| Go (RE2) | No (not needed) | No (not needed) |
What problem they solve
A pattern like (a+)+$ against a long string of as followed by a non-match can force the engine to try astronomically many combinations — this is catastrophic backtracking, and it can freeze a program for seconds or minutes. Atomic groups and possessive quantifiers tell the engine: "once you have matched this, never give any of it back." That collapses the search space and makes the failure fast instead of fatal.
Example
// Java — possessive + prevents backtracking blow-up
Pattern p = Pattern.compile("(a++)+$"); // fails fast, no hang
// Atomic-group equivalent:
Pattern.compile("(?>a+)+$");
If your engine lacks them
- JavaScript: no atomic groups — rewrite the pattern to avoid nested quantifiers, or emulate atomicity with a lookahead capture trick:
(?=(a+))\1. - Go: not applicable — RE2 cannot catastrophically backtrack in the first place, so it needs no possessive syntax.
FAQ
What is the difference between a++ and a+?
a+ is greedy but will backtrack (give characters back) if the rest of the pattern fails. a++ is possessive: it keeps everything it matched and never backtracks, which prevents catastrophic backtracking.
Does JavaScript support atomic groups?
No. JavaScript has neither atomic groups (?>...) nor possessive quantifiers. You can emulate atomicity with a lookahead-plus-backreference trick: (?=(pattern))\1.
Do I need possessive quantifiers in Go?
No. Go's RE2 engine matches in guaranteed linear time and cannot catastrophically backtrack, so possessive quantifiers are unnecessary and unsupported.