JS: 'caaandy'.match(/ca*/)
Py: re.findall(r'bo*', 'A bird booed and a bobcat roared')
output
JS: "caaa"
Py: ["boo", "bo", "b"]
Note * is greedy by default -- it matches as many characters as possible. Beware: .* can match empty strings and lead to unexpected results at every position in a string.
zero or morestar quantifierrepeat zero plusasterisk
+ One or More
syntax
a+ matches one or more 'a' characters
example
JS: 'caaandy candy cdy'.match(/ca+ndy/g)
Py: re.findall(r'\d+', 'There are 12 cats and 340 dogs')
output
JS: ["caaandy", "candy"]
Py: ["12", "340"]
Note Unlike *, the + quantifier requires at least one occurrence. This is the most common quantifier for extracting sequences of digits, letters, etc.
one or moreplus quantifierat least onerepeat one plus
? Optional (Zero or One)
syntax
a? matches zero or one 'a'
example
JS: 'color colour'.match(/colou?r/g)
Py: re.findall(r'https?://', 'http://a.com and https://b.com')
Note Useful for minimum-length validation. Remember this is greedy -- it will consume as much as possible.
minimum countat least n timesn or moreminimum length
Greedy vs Lazy Matching
syntax
Greedy: .* .+ .? Lazy: .*? .+? .??
example
JS: '<b>bold</b> and <b>more</b>'.match(/<b>.*<\/b>/)
JS: '<b>bold</b> and <b>more</b>'.match(/<b>.*?<\/b>/)
output
Greedy: "<b>bold</b> and <b>more</b>" (longest match)
Lazy: "<b>bold</b>" (shortest match)
Note Greedy quantifiers eat as much as possible, then backtrack. Lazy quantifiers match as little as possible, then expand. This distinction is critical when parsing HTML, quoted strings, or any delimited content. Always prefer lazy when you want the nearest closing delimiter.
greedy matchinglazy matchingnon-greedyminimal matchshortest matchlongest match
Lazy Quantifier Variants
syntax
*? +? ?? {n,m}? {n,}?
example
JS: '"hello" and "world"'.match(/"[^"]+?"/g)
Py: re.findall(r'\d{2,4}?', '12345')
Note Append ? after any quantifier to make it lazy. {2,4}? prefers matching 2 characters instead of 4. For the quoted-string case, a negated class [^"]+ is often more efficient than a lazy .+? approach.
*+ ++ ?+ {n,m}+ (not supported in JS or Python re)
example
Java/PCRE: '"hello"'.match(/"[^"]*+"/)
Python alternative: use atomic group via regex module
import regex
regex.search(r'"(?>"[^"]*)"+', text)
output
Matches "hello" without backtracking into the quoted content
Note Possessive quantifiers never give back characters once matched. They prevent catastrophic backtracking but cause a match to fail if the rest of the pattern cannot match. Not available in JavaScript or Python's built-in re module -- use the third-party 'regex' module in Python or atomic groups in PCRE.