Understanding Quantifiers: Plus, Asterisk, and Question Mark
Greedy quantifiers expand to match the last occurrence of a pattern; non-greedy quantifiers match the first occurrence.
When a Match Goes Too Far
A regular expression can match more text than you intended when its quantifier is greedy. Greedy quantifiers expand as far as they can and settle at the last valid stopping point. Non-greedy quantifiers take the opposite approach: they stop at the first point where the rest of the pattern can be satisfied.
What do you think happens?
Suppose .+ is applied to a string containing several @ symbols, with no pattern after the quantifier. Where will the match end?
Reveal answer
Answer: At the last valid stopping point
The greedy quantifier initially consumes as much as it can. Because there is nothing after the @ in this pattern that would force an earlier stop, the match settles at the last valid stopping point.
Expansion Toward the Last Match
Think of a greedy quantifier as having a choice about where to stop. With .+, the engine matches one or more characters and initially keeps consuming characters, moving toward the end of the string. It then checks whether the rest of the pattern is satisfied. If it is, the quantifier settles at that final valid stopping point. This is why a greedy pattern can include text from earlier delimiters when several delimiters appear in the same string.
The diagram shows the direction of the greedy search: begin matching, keep expanding, and stop only at the last point that still produces a valid match. The quantifier does not automatically stop at the first delimiter it encounters.
The Question-Mark Conversion
Appending a question mark to a greedy quantifier makes that quantifier non-greedy. The common conversions are .+ to .+? and .* to .*?. A non-greedy quantifier still tries to satisfy the pattern, but it stops as soon as the rest of the pattern can be satisfied.
| Pattern form | Matching behavior | Typical stopping goal |
|---|---|---|
| .+ | Greedy; matches one or more characters and expands as far as it can | Last valid stopping point |
| .+? | Non-greedy; matches one or more characters but stops as soon as possible | First valid stopping point |
| .* | Greedy form shown in the source material | Expand toward the last valid stopping point |
| .*? | Non-greedy form shown in the source material | Stop at the first valid stopping point |
The question mark in .+? or .*? is not being used here as an independent matching choice. It is appended to the quantifier to request non-greedy behavior. The key debugging question is therefore: should this pattern reach the last valid occurrence, or should it stop at the first one?
Tracing the Email-List Example
Comparing .+@ with .+?@
Consider a string containing several email addresses, including stephen.marquard@uct.ac.za. Compare a greedy pattern .+@ with the non-greedy pattern .+?@.
Greedy start: With .+@, the .+ portion initially consumes as much text as it can while the expression searches for a valid @ position.
Greedy stopping point: Because the quantifier is greedy, the match settles at the last valid @ position rather than stopping at the first @ position.
Non-greedy conversion: Changing .+@ to .+?@ appends a question mark to the quantifier.
Non-greedy stopping point: With .+?@, the engine still matches one or more characters, but stops as soon as the following @ can satisfy the pattern. In the source example, this is the @ in stephen.marquard@uct.ac.za.
The greedy form reaches the last valid @ position, while the non-greedy form reaches the first valid @ position.
Extracting Between Delimiters
The choice between greedy and non-greedy matching depends on the extraction goal. If a string contains multiple delimiters and you want an individual item, non-greedy matching is often safer because it aims for the first valid stopping point. If the goal is to include text through the last valid occurrence, greedy matching is the appropriate direction.
Generated example: imagine text containing several bracketed items such as [first] and [second]. A greedy pattern intended to find text ending at a closing bracket may continue toward a later valid closing bracket. A non-greedy version is often a better starting point when the goal is to extract one item at a time rather than the largest span.
Mistakes in Quantifier Debugging
Assuming a greedy quantifier stops at the first delimiter.
Greedy matching expands toward the last valid stopping point.
Fix:
Try .+?@ when the goal is to stop at the first @ that satisfies the pattern.Changing the matching characters instead of changing quantifier greediness.
The issue may be where the quantifier stops, not which basic pattern is being matched.
Fix:
Append ? to convert .+ to .+? or .* to .*? and then reassess the captured span.Choosing greedy or non-greedy without defining the extraction goal.
Neither behavior is universally correct; the choice depends on whether the first or last match is wanted.
Fix:
State the target explicitly: first valid occurrence or last valid occurrence.Treating .*? and .+? as identical.
The source distinguishes .+? as matching one or more characters, while .*? is presented as the non-greedy counterpart of .*.
Fix:
Preserve the original quantifier form and append the question mark when converting its greediness.
Practice the Stopping Point
A text string contains several @ symbols. You need a pattern that matches from the beginning of the string through the first @ symbol. Should you begin with .+@ or .+?@? Explain what the question mark changes.
Hints
- Identify whether the goal is the first or last valid occurrence.
- A question mark appended to a quantifier makes it non-greedy.
- The non-greedy form stops as soon as the rest of the pattern can be satisfied.
You are extracting individual items from text with multiple delimiters, but your current greedy pattern captures too large a span. Describe the smallest change you would test first and why.
Hints
- Start by asking whether the first valid delimiter is the intended stopping point.
- Convert the relevant greedy quantifier to its non-greedy form.
- Compare the resulting match with the original captured span.
Key Takeaways
- Greedy quantifiers expand and settle at the last valid stopping point.
- Non-greedy quantifiers stop as soon as the rest of the pattern can be satisfied.
- Append ? to convert .+ into .+? or .* into .*?.
- Use greedy matching when the last valid occurrence is wanted and non-greedy matching when the first valid occurrence is wanted.
- When a match captures too much, test the non-greedy form before making larger changes.
Key Takeaways
- Greedy matching keeps expanding toward the last valid occurrence.
- Appending a question mark makes a quantifier non-greedy.
- The non-greedy forms .+? and .*? aim for the first valid stopping point.
- The correct choice depends on whether the task requires the first match or the last match.
- For text extraction with multiple delimiters, beginning with non-greedy matching is often safer.