Concept

Lazy vs. Greedy Quantifiers

Greedy quantifiers (*, +) consume as much as possible before backtracking. Lazy quantifiers (*?, +?) consume as little as possible.

The default is greedy

By default, + and * match as many characters as they can while still allowing the overall pattern to succeed. On <.+>, the .+ will race to the end of the string and then backtrack one character at a time until the final > is found — often capturing far more than intended.

Greedy — over-captures

Try this
/<.+>/

Input

<b>bold</b> and <i>italic</i>

Result

Match: <b>bold</b> and <i>italic</i> (the whole thing)

Adding ? makes the quantifier lazy

+? and *? switch to lazy (also called non-greedy or reluctant) matching. They match as few characters as possible, expanding only when needed to complete the overall match.

Lazy — matches each tag separately

Try this
/<.+?>/g

Input

<b>bold</b> and <i>italic</i>

Result

Matches: <b>, </b>, <i>, </i>

When to use which

Default to greedy when you want the longest possible match — numeric sequences, whole-word captures. Switch to lazy when you're matching to a specific terminator that could appear multiple times, like HTML tags, quoted strings, or multi-line comments.

Alternative: a negated character class

<[^>]+> is often better than <.+?> for tags — it directly says 'anything that isn't >.' It's faster (no backtracking) and clearer about intent. Use lazy quantifiers when the terminator can't be expressed as a single character set.

Related patterns

All reference guidesOpen the RegexPro tester →