Concepts / Greedy vs. Non-Greedy Matching

Greedy vs. Non-Greedy Matching

A greedy quantifier expands as far as it can and settles on the last occurrence that still allows the pattern to succeed.

  • Programming
Interactive lab

Try it: Regular expressions: a backtracking matcher

How Python's re module matches a pattern: it tries each start position, matches tokens one by one, lets greedy quantifiers take as much as possible and give it back when the rest fails (lazy ones take as little as possible), tries alternatives in order and records groups.

How it works

  1. search tries start positions 0, 1, 2 …; match tries only position 0; findall collects every non-overlapping match.
  2. Tokens are matched left to right: literals, ., classes like [a-c] and \d, and zero-width anchors ^, \$, \b.
  3. A greedy quantifier (* + ? {m,n}) takes as many repetitions as it can, then backtracks one at a time; a lazy one (*? +? ??) takes as few as possible and grows only when needed.
  4. Alternatives in a | b are tried in order; the first that lets the whole pattern match wins.
  5. Parentheses capture the text their part matched; captures are undone when the matcher backtracks past them.

Default run (63 steps): re.search('(\\w+)@(\\w+)\\.com', 'mail bo@ikb.com now'): try each start position until one matches. … re.search('(\\w+)@(\\w+)\\.com', 'mail bo@ikb.com now') → <re.Match object; span=(5, 15), match='bo@ikb.com'>

Simplified: A subset of re: no flags, lookarounds, backreferences, named groups or possessive quantifiers; pattern and text up to 24 printable ASCII characters. The trace stops after 1900 attempts ("too many steps") where real Python would keep backtracking.

Educational simulation

Loading the simulation…

The Stopping-Point Problem

Regular-expression patterns often have more than one possible place where they could stop. A greedy quantifier expands as far as it can and settles on the last occurrence that still allows the pattern to succeed. A non-greedy quantifier stops at the first occurrence that satisfies the rest of the pattern. The $ anchor adds a different kind of constraint: it requires the match to end at the end of a line.

What do you think happens?

Suppose a pattern uses .+ before an @ symbol in a string containing several @ symbols. Will .+ normally stop at the first @ or continue toward the last possible @?

  • It stops at the first @

  • It continues toward the last possible @

  • It cannot match an @ symbol

Reveal answer
Answer:

It continues toward the last possible @.

The greedy quantifier .+ expands as much as possible. It settles at the last valid stopping point for which the remaining pattern can still succeed.

Greedy Expansion

The plus quantifier means one or more characters. When it is written as .+, the dot-and-plus combination is greedy. It initially consumes as much text as possible, then settles at the last position where the rest of the pattern can still be satisfied. If the pattern is .+ followed by @, the greedy portion expands toward the last usable @ rather than stopping at the first one.

.+@greedylast @last valid stopping point.+?@non-greedyfirst @first valid stopping pointexpands tostops at
How does changing .+ to .+? change which @ symbol ends the match?
Worked example

Choosing the Match Around @ Symbols

Compare .+@ and .+?@ when the text contains the email list example stephen.marquard@uct.ac.za.

  1. 1
    Greedy pattern

    The .+ portion expands as far as possible before the @ that completes the pattern. It therefore aims for the last valid @ symbol in the available text.

  2. 2
    Non-greedy pattern

    Adding ? changes .+ to .+?. The quantifier stops as soon as the rest of the pattern can succeed, so it aims for the first @ symbol.

  3. 3
    Selection rule

    Use the greedy form when the last valid occurrence is the intended boundary. Use the non-greedy form when the first valid occurrence is the intended boundary.

Result

Greedy and non-greedy forms use the same basic repetition, but they choose different stopping points.

The Line Ending Anchor

Definition

The $ symbol is a positional anchor that marks the end of a line. It does not match a literal dollar-sign character. A pattern such as end$ matches end only when end appears at the line ending.

The anchor changes where a successful match is allowed to finish. In This is the end, end$ can match because end is at the line ending. In end of the story, end$ does not match because additional characters follow end.

endliteral textline endingrequired position$line-ending anchorfollowed byrequires
How does the $ anchor restrict a pattern to the line ending, and how is that different from matching a literal dollar sign?

Greedy Matching at Line End

A greedy quantifier and the $ anchor can work together. In [0-9.]+$, the character class must match one or more digits or literal periods, and the complete match must reach the line ending. Because the match must finish at the end, the greedy quantifier expands through the final sequence that can satisfy the character class and the anchor.

0.8475earlier eligible sequence[0-9.]+can match an eligiblesequence0.0000line-ending sequence[0-9.]+$must reach line endingmay matchmatches at line end
How does combining a greedy character class with $ make the match reach the final eligible value at the line ending?
PatternPosition requirementExtraction behavior
[0-9.]+No line-ending requirementCan match an eligible sequence encountered earlier
[0-9.]+$Must finish at the line endingTargets an eligible sequence that extends to the line end

An open-ended character-class pattern and the same pattern with a line-ending anchor serve different extraction goals.

Literal Periods in Character Classes

A period outside a character class can have wildcard behavior in regular-expression patterns. Inside square brackets, however, the period loses that wildcard meaning and matches only a literal period. Therefore, [0-9.]+ is suitable for sequences made from digits and periods, such as 0.8475.

.wildcard behavior.literal period[0-9.]allowed characterschanges meaning insideincludes
How does a period behave inside a character class compared with a period used outside one?
Key point

The brackets are not decorative: they define a set of allowed characters. In [0-9.]+, the set contains digits and the literal period, so the class does not treat every character as acceptable.

Searching Before Extracting

A useful structured pattern can first identify the shape of a line and then extract the value at its end. The source pattern begins with X, allows any characters in between, requires a colon and a space, and finishes with [0-9.]+$. The final anchor ensures that the digits-and-periods portion continues through the line ending rather than stopping at an earlier eligible sequence.

structured lineinput textX.*line prefix$line ending:required separator[0-9.]+digits and periodssearchesreachesextractsmust reach
How does a regular expression identify a structured line and then extract the intended value at its end?
Worked example

Selecting the End Value

A structured line contains an earlier digit sequence and a confidence value at the end. Compare an open-ended [0-9.]+ pattern with [0-9.]+$.

  1. 1
    Open-ended search

    Without $, [0-9.]+ is not required to finish at the line ending, so it can match the first eligible digit-and-period sequence encountered.

  2. 2
    Anchored search

    With $, the eligible sequence must extend to the line ending. The match therefore targets the final value when that value is made from digits and periods.

  3. 3
    Extraction decision

    The anchored form is appropriate when the data of interest is consistently located at the end of each structured line.

Result

Adding $ changes the positional requirement from anywhere in the line to the line ending.

Choosing the Quantifier

GoalUseful choiceReason
Reach the last valid occurrenceGreedy quantifier such as .+The quantifier expands as far as possible while allowing the pattern to succeed
Stop at the first valid occurrenceNon-greedy quantifier such as .+?The question mark makes the quantifier stop as soon as the rest of the pattern can succeed
Require a value at the line endingAn end anchor such as [0-9.]+$The match must finish at the line ending
Match data without caring about its line-ending positionAn open-ended pattern without $No end-of-line constraint is added

Greediness controls how far a repeated part expands; $ controls where the complete pattern must end.

[0-9.]+no ending constraintearlier eligiblevaluemay be selected[0-9.]+$must reach line endingline-ending valuetargetedcan matchmust match
What changes when an open-ended extraction pattern is changed to require the line ending?

Common Matching Mistakes

  • Common mistake

    Treating $ as a literal dollar-sign character

    What it looks like

    Using $ when the intended meaning is a currency symbol

    Why it fails

    In regular expressions, $ is a positional anchor marking the end of a line.

    Do this instead

    Interpret $ as an end-of-line requirement in this context.

  • Common mistake

    Using an open-ended pattern when the desired value is at the line ending

    What it looks like
    [0-9.]+
    Why it fails

    The pattern is not required to continue through the line ending, so it may match an earlier eligible sequence.

    Do this instead

    Use [0-9.]+$ when the digits-and-periods value must reach the end of the line.

  • Common mistake

    Assuming the period inside [0-9.] is a wildcard

    What it looks like

    Expecting [0-9.]+ to accept any character between digits

    Why it fails

    Inside square brackets, the period matches only a literal period.

    Do this instead

    Read [0-9.] as a character class containing digits and the literal period.

  • Common mistake

    Using a greedy quantifier when the first delimiter is the intended boundary

    What it looks like
    .+@
    Why it fails

    The greedy .+ expands toward the last valid @.

    Do this instead

    Use .+?@ when the intended boundary is the first @.

  • Common mistake

    Using a non-greedy quantifier when the last occurrence is required

    What it looks like
    .+?@
    Why it fails

    The non-greedy form stops at the first @ that allows the pattern to succeed.

    Do this instead

    Use a greedy form such as .+@ when the last valid occurrence is the intended stopping point.

Practice the Decision

MEDIUM

For each situation, choose the more suitable pattern form: a greedy quantifier, a non-greedy quantifier, an open-ended character class, or the same character class followed by $. Then explain whether your goal is the first valid occurrence, the last valid occurrence, or a value that reaches the line ending.

Hints
  • Ask whether the pattern should stop at the first or last valid delimiter.
  • Ask whether the extracted value must be at the end of the line.
  • Remember that adding ? to a quantifier makes it non-greedy.
  • Remember that a period inside [0-9.] is literal.
  1. 1
    Use greediness to control which valid occurrence becomes the stopping point. Use $ to control where the complete match must finish. These are separate decisions: a pattern can be greedy without being end-anchored, or it can combine a greedy character class with $ to extract a value that extends to the line ending.

Key Takeaways

  • $ marks the end of a line in a regular expression; it does not match a literal dollar sign.
  • Greedy quantifiers expand toward the last valid occurrence, while non-greedy quantifiers stop at the first valid occurrence.
  • Appending ? changes a greedy quantifier such as .+ or .* into a non-greedy form such as .+? or .*?.
  • The pattern [0-9.]+$ targets a sequence of digits and literal periods that reaches the line ending.
  • Inside a character class, the period matches a literal period rather than acting as a wildcard.

More concepts starting with G