Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversHalloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PC×
Skip to content
World desk4 min

Greedy vs. Non-Greedy Regex: How to Read an Unexpected Match

Greedy quantifiers try more repetitions first; lazy quantifiers try fewer. The rest of the pattern—and the regex engine—determines the final match.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

In JavaScript, a greedy quantifier tries to repeat its preceding atom as many times as it can; a lazy (non-greedy) quantifier tries as few times as possible. The rest of the pattern still has to match, so a greedy quantifier may give characters back and a lazy one may take more. The difference is a preference in how repetition is tried—not a rule that the final match must always be longest or shortest.

What changes when you add ? to a quantifier?

Quantifiers such as *, +, ?, and {n,m} specify how often the preceding atom may repeat. In JavaScript, these quantifiers are greedy by default: they try more repetitions first. Put a second question mark after the quantifier—such as *?, +?, ??, or {n,m}?—and it becomes lazy: it tries fewer repetitions first, then takes more if needed for the rest of the pattern to match. MDN’s JavaScript quantifier reference describes these forms.

As an Amazon Associate I earn from qualifying purchases.

The question mark changes the order of attempts, not what characters the quantified atom is allowed to match. For example, .* and .*? can both match characters permitted by the dot; they differ in how many they try to consume before checking what comes next.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why does .* match too much?

Consider the JavaScript input <foo> <bar>:

Pattern Result Reason
/<.*>/ <foo> <bar> .* tries to consume as much as it can while leaving a closing > for the pattern. The last closing bracket allows the whole pattern to succeed.
/<.*?>/ <foo> .*? starts with fewer characters and stops at the first closing bracket that lets the pattern succeed.

Read each pattern from left to right: < matches the opening delimiter, .* or .*? matches repeated characters, and > requires a closing delimiter. MDN’s JavaScript regular-expression syntax guide documents this delimiter example and the role of quantifiers.

Why can a greedy quantifier give characters back?

A quantifier’s preference is not the only constraint. The engine must also match the tokens that follow it. In a backtracking engine, a greedy quantifier first takes more repetitions; if the later part fails, it can give some back and try again. A lazy quantifier does the reverse: it starts with fewer repetitions and expands when the suffix cannot yet match.

For example, with a pattern that requires a particular letter after .*, the greedy quantifier may initially pass that letter, then backtrack until the required letter can match. With .*?, the engine may first try the suffix too early, then consume more text until the suffix succeeds. In both cases, judge the complete pattern rather than the quantifier alone.

How to diagnose an unexpected match

  1. Find the starting position. Identify where the engine begins looking for a match. In JavaScript, once a match succeeds at a starting position, the engine does not keep searching later positions solely to find a longer overall match.
  2. Identify the repeated atom. A quantifier applies only to the atom immediately before it. To repeat a larger expression, group it—for example, use (ab)+ to repeat the two-character sequence ab.
  3. Read the required suffix. Work out what must match after the quantifier, and check where that suffix can first succeed.
  4. Trace the attempts. For a greedy quantifier, consider the most repetitions first and then any give-back needed. For a lazy quantifier, consider the fewest first and then any expansion needed.
  5. Check the engine and flags. Syntax and selection behavior can vary by regex flavor, and flags can affect which characters tokens such as the dot match. Verify the behavior for the language and version you are using.

Does this work the same way in every language?

The greedy-versus-lazy distinction exists in several common regex flavors, but not every implementation shares all syntax or match-selection details. The Python 3.14.8 re documentation describes greedy and non-greedy forms, while the Python regular-expression HOWTO explains their behavior. The Java SE 20 Pattern reference documents greedy quantifiers for Java’s API. Treat examples as flavor-specific: when a result matters, consult the documentation for the exact engine and version rather than assuming all regex implementations behave identically.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Lazy is not possessive

Lazy quantifiers still allow the engine to try more repetitions when the rest of the pattern needs them. Python 3.11 added possessive quantifiers, a different feature: they do not backtrack. As a result, a possessive quantifier can make a pattern fail where an ordinary greedy quantifier could give characters back. Python’s official re reference documents this distinction.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

When should you use .*??

Use a lazy quantifier when you want the pattern to try the nearest qualifying boundary first—for example, the first closing delimiter in a simple string. Use a greedy quantifier when taking as much as possible before the required suffix is the intended preference. Neither form, by itself, guarantees that the match is well-formed or structurally meaningful; the surrounding pattern and input determine what succeeds.

If the delimiters can contain nested structures or escaped closing characters, a simple .*? may stop at a delimiter that is not the true end of the structure. In that situation, design the pattern around the actual allowed content, or use a parser when the input has nested syntax.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.