gotchajavascriptModerate
Non-greedy quantifiers to avoid over-matching
Viewed 0 times
non-greedylazy quantifiergreedy matchover-matchregex quantifier
Problem
Greedy quantifiers like . match as much as possible. Matching HTML tags with <.> on a string with multiple tags returns the entire string instead of individual tags.
Solution
Append ? to make a quantifier lazy (non-greedy): .*? matches as little as possible.
const greedy = /<.*>/g;
'<b>bold</b> <i>italic</i>'.match(greedy);
// ['<b>bold</b> <i>italic</i>'] — wrong
const lazy = /<.*?>/g;
'<b>bold</b> <i>italic</i>'.match(lazy);
// ['<b>', '</b>', '<i>', '</i>'] — correct
const greedy = /<.*>/g;
'<b>bold</b> <i>italic</i>'.match(greedy);
// ['<b>bold</b> <i>italic</i>'] — wrong
const lazy = /<.*?>/g;
'<b>bold</b> <i>italic</i>'.match(lazy);
// ['<b>', '</b>', '<i>', '</i>'] — correct
Why
Greedy quantifiers backtrack from the rightmost possible match. Lazy quantifiers expand from the leftmost minimum, stopping as soon as the rest of the pattern can match.
Gotchas
- Lazy quantifiers can still be slow when the pattern requires extensive backtracking
- A negated character class [^>] is faster and clearer than .? for many cases
- Do not use regex to parse HTML in production — use a proper DOM parser
Code Snippets
Greedy vs lazy vs negated class
// Greedy — wrong
/<.*>/g.exec('<a>link</a>'); // '<a>link</a>'
// Lazy — correct for simple cases
/<.*?>/g;
// Even better: negated class (no backtracking)
/<[^>]*>/g;Revisions (0)
No revisions yet.