Regex with Nested Quantifiers
This is a teaching pattern for catastrophic backtracking risk. It looks simple, but nested quantifiers can turn certain non-matching inputs into expensive regex evaluations.
The expression
/^(a+)+$/How to read it
Anchor: the match must start at the beginning of the string.
Anchor: the match must run to the end of the string.
Nested quantifiers — the shape behind catastrophic backtracking.
Do not run this on untrusted input
This expression contains nested quantifiers, so an input that nearly matches can force the engine through an exponential number of attempts before it fails. On a public endpoint that is a denial-of-service vector. Rewrite it with a possessive or atomic construct, cap the input length, or validate with a parser instead.
Validate your own text, line by line
no inputThis expression is anchored, so it asks whether a whole string is valid. Each line above is tested on its own — it will not find a match inside a longer sentence.
Examples, checked in your browser
4/4 verifiedaaaa
Simple repeated input matches.
aaaaaaaaaaaaaaaa!
A trailing non-match is where backtracking cost spikes.
b
No match — this is the kind of input the pattern rejects.
(empty string)
No match — this is the kind of input the pattern rejects.
Use it in code
3 languagesconst regex = /^(a+)+$/g;
regex.test(input);import re
pattern = re.compile(r"^(a+)+$")
bool(pattern.search(input))re := regexp.MustCompile("^(a+)+$")
matched := re.MatchString(input)Other validation patterns
6Valid Email Address
/^[^\s@]+@[^\s@]+\.[^\s@]+$/i
URL Slug
/^[a-z0-9]+(?:-[a-z0-9]+)*$/
Strong Password
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z\d]).{12,}$/
UUID v4
/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
IPv4 Address
/^(?:25[0-5]|2[0-4]\d|1?\d?\d)(?:\.(?:25[0-5]|2[0-4]\d|1?\d?\d)){3}$/
Hex Color
/^#?(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/