skip to content

Quantifiers: Greedy, Lazy & Possessive

Greedy quantifiers take as much as possible and backtrack, lazy ones take as little as possible, and possessive ones never give anything back. Possessive quantifiers and atomic groups are the fix for catastrophic backtracking, which is where interviewers are heading.

part ofJavaoverview, primer and where to startread it →
on this pageshow

questions

4

What are the basic regex quantifiers in Java (* + ? and {n}/{n,}/{n,m}) and what does each one match?

level: juniorimportance: must knowfreq 72%

answer

  1. = zero+, + = one+, ? = zero/one
  2. {n} exact, {n,} at least, {n,m} range
  3. Binds to ONE atom — group with () to repeat a sequence
  4. No space in {2,4}

basics

~20 s

Quantifiers say how many times the thing before them may repeat. * means zero or more, + means one or more, ? means zero or one. {n} means exactly n, {n,} means n or more, {n,m} means between n and m.

solid answer

~40 s

A quantifier in a regular expression controls how many times the preceding element (a single character, a character class, or a group) may repeat. Java's java.util.regex supports the three shorthand quantifiers and the explicit brace form. '*' matches zero or more times, '+' matches one or more times, and '?' matches zero or one time (optional). The brace form is explicit: '{n}' matches exactly n times, '{n,}' matches at least n times, and '{n,m}' matches between n and m times inclusive. So 'a*' matches '', 'a', 'aa'; 'a+' needs at least one 'a'; 'a?' matches '' or 'a'; 'a{2,4}' matches two to four 'a's. A quantifier attaches only to the single token immediately before it, so to repeat a multi-character sequence you wrap it in a group: '(ab)+'.

go deeper

for a junior

Can name *, +, ?, and the brace forms and say what each matches; knows + needs at least one.

for a middle

Knows quantifiers bind to a single atom and that you group to repeat sequences; uses the brace range correctly without spaces.

for a senior

Explains the shorthand-to-brace equivalences and reasons about edge cases like empty-string matches with *.

for a principal

Frames quantifier choice in terms of validation strictness and pattern maintainability across a codebase.

## What a regex and a quantifier are A **regular expression** (regex) is a small pattern language for describing sets of strings. In Java you compile a pattern with `Pattern.compile("...")` and test or search text with a `Matcher`. A **quantifier** is the part of a regex that says *how many times* the thing immediately before it is allowed to repeat. The 'thing before' is a single **atom**: one literal character (`a`), one escape (`\d` = a digit), one **character class** (`[a-z]` = one lowercase letter), or one **group** in parentheses (`(ab)`). A quantifier binds to exactly that one atom — not to everything to its left. ## The three shorthand quantifiers - `*` — **zero or more**. `a*` matches the empty string, `a`, `aa`, `aaa`, ... It can match nothing at all. - `+` — **one or more**. `a+` requires at least one `a`; it will not match the empty string. - `?` — **zero or one** (i.e. 'optional'). `a?` matches `` or `a` but never `aa`. ## The explicit brace form `{...}` Braces let you state an exact count or a range: - `{n}` — **exactly n**. `a{3}` matches only `aaa`. - `{n,}` — **at least n**. `a{2,}` matches `aa`, `aaa`, ... - `{n,m}` — **between n and m inclusive**. `a{2,4}` matches `aa`, `aaa`, `aaaa`. Note there is no space after the comma in Java's syntax: write `{2,4}`, not `{2, 4}`. The shorthands are just aliases: `*` = `{0,}`, `+` = `{1,}`, `?` = `{0,1}`. ## Binding: quantifier attaches to one atom `ab+` means `a` followed by one-or-more `b` (matches `ab`, `abb`), **not** one-or-more `ab`. To repeat a sequence, group it: `(ab)+` matches `ab`, `abab`. Likewise `[0-9]{3}` matches exactly three digits because the class `[0-9]` is the single atom the `{3}` repeats. ## A worked example Pattern `\d{2,4}` against `"12345"`: it matches the first four digits `1234` (the maximum allowed in the range), leaving `5`. Pattern `colou?r` matches both `color` and `colour` because the `u` is optional. ## Why this matters Quantifiers are the most common source of both power and bugs in regex. Getting the count right (e.g. `{1,}` vs `{0,}`) is the difference between requiring data and accepting empty input — directly relevant to input validation.

  • How do you make a quantifier apply to more than one character?
    Wrap the characters in a group with parentheses, e.g. (abc)+ repeats the whole sequence 'abc' one or more times.
  • What is the shorthand equivalent of {0,1}?
    The ? quantifier — both mean 'optional', zero or one occurrence.

saying these in an interview costs you the question

  • Thinking + matches zero occurrences (it requires at least one)
  • Believing ab+ means one-or-more 'ab' (it's a then b+)
  • Writing {2, 4} with a space — Java treats it as a literal in some contexts and it won't behave as a range

context

open as a page

What is the difference between greedy and reluctant (lazy) quantifiers in Java regex, and when does it matter?

level: middleimportance: must knowfreq 68%

basics

~20 s

Greedy quantifiers (the default) grab as much text as possible, then give some back if needed. Lazy quantifiers, written with a trailing ?, grab as little as possible and only take more if forced. They differ in how much text each match consumes.

open as a page

What are possessive quantifiers in Java, how do they differ from greedy ones, and what are atomic groups?

level: seniorimportance: should knowfreq 48%

basics

~20 s

A possessive quantifier (written with a trailing +, like a++) grabs as much as it can and then never gives any of it back — it disables backtracking for that part. An atomic group (?>...) does the same thing for a whole subpattern.

open as a page

What is catastrophic backtracking (ReDoS) in regex, how do quantifiers cause it, and how do you prevent it in a Java service?

level: principalimportance: should knowfreq 40%

basics

~20 s

Catastrophic backtracking happens when nested or overlapping quantifiers give the engine exponentially many ways to match, so a crafted input makes one regex run effectively forever. An attacker can use this to freeze a thread — that's ReDoS. You prevent it with possessive quantifiers, atomic groups, or unambiguous patterns.

open as a page