Greedy vs. Non-Greedy Matching
The $ anchor marks the end of a line in regular expressions, not a literal dollar sign character
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 @?
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.
Choosing the Match Around @ Symbols
Compare .+@ and .+?@ when the text contains the email list example stephen.marquard@uct.ac.za.
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.
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.
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.
Greedy and non-greedy forms use the same basic repetition, but they choose different stopping points.
The Line Ending Anchor
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.
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.
| Pattern | Position requirement | Extraction behavior |
|---|---|---|
| [0-9.]+ | No line-ending requirement | Can match an eligible sequence encountered earlier |
| [0-9.]+$ | Must finish at the line ending | Targets an eligible sequence that extends to the line end |
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.
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.
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.]+$.
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.
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.
Extraction decision: The anchored form is appropriate when the data of interest is consistently located at the end of each structured line.
Adding $ changes the positional requirement from anywhere in the line to the line ending.
Choosing the Quantifier
| Goal | Useful choice | Reason |
|---|---|---|
| Reach the last valid occurrence | Greedy quantifier such as .+ | The quantifier expands as far as possible while allowing the pattern to succeed |
| Stop at the first valid occurrence | Non-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 ending | An end anchor such as [0-9.]+$ | The match must finish at the line ending |
| Match data without caring about its line-ending position | An open-ended pattern without $ | No end-of-line constraint is added |
Common Matching Mistakes
Treating $ as a literal dollar-sign character
In regular expressions, $ is a positional anchor marking the end of a line.
Fix:
Interpret $ as an end-of-line requirement in this context.Using an open-ended pattern when the desired value is at the line ending
The pattern is not required to continue through the line ending, so it may match an earlier eligible sequence.
Fix:
Use [0-9.]+$ when the digits-and-periods value must reach the end of the line.Assuming the period inside [0-9.] is a wildcard
Inside square brackets, the period matches only a literal period.
Fix:
Read [0-9.] as a character class containing digits and the literal period.Using a greedy quantifier when the first delimiter is the intended boundary
The greedy .+ expands toward the last valid @.
Fix:
Use .+?@ when the intended boundary is the first @.Using a non-greedy quantifier when the last occurrence is required
The non-greedy form stops at the first @ that allows the pattern to succeed.
Fix:
Use a greedy form such as .+@ when the last valid occurrence is the intended stopping point.
Practice the Decision
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.
- 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.