/^/

Lesson 6 of 28

Quantifiers

Controlling how many times a piece of a pattern repeats: *, +, ?, {n}, {n,}, and {n,m}.

6 min read

Every pattern you’ve written so far matches each piece exactly once. Quantifiers change that: they attach to the character, class, or group immediately before them and say how many times it’s allowed to repeat.

The three symbols: *, +, ?

Quantifier Meaning Example Matches
* Zero or more ab*c ac, abc, abbbc, …
+ One or more ab+c abc, abbbc, … but not ac
? Zero or one ab?c ac or abc only
/ab*c/.test("ac");     // true — zero b's is fine
/ab+c/.test("ac");     // false — + requires at least one b
/ab?c/.test("abbc");   // false — ? allows at most one b
ac abc abbbc
3 matches

The demo shows ab*c matching all three variants — ac (zero b’s), abc (one b), and abbbc (three b’s) — because * places no upper bound on how many b characters can appear.

Exact counts with {n}, {n,}, and {n,m}

Curly-brace quantifiers give you precise control instead of the fixed “zero/one/many” meanings above:

  • {n} — exactly n repetitions
  • {n,}n or more repetitions, no upper limit
  • {n,m} — between n and m repetitions, inclusive
/^\d{3}$/.test("42");      // false — only 2 digits
/^\d{3}$/.test("425");     // true — exactly 3 digits
/^\d{3,}$/.test("42599");  // true — 3 or more is fine
/^\d{2,4}$/.test("42599"); // false — 5 digits is too many
1 12 123 12345
3 matches

Watch the last group in the demo carefully: against "12345", the pattern \d{2,4} matches 1234 — the engine grabs as many digits as it’s allowed (up to 4) starting from the first available position, leaving the trailing 5 as a separate, too-short leftover that doesn’t get matched on its own since a lone digit doesn’t satisfy {2,4}.

Tip

*, +, and ? are really just shorthand for common {n,m} ranges: * is {0,}, + is {1,}, and ? is {0,1}. They’re written as symbols purely because they come up so often.

Greedy by default

All the quantifiers above are greedy by default — they try to match as much as possible first, and only give back characters (backtrack) if that’s the only way for the rest of the pattern to succeed. That’s why \d{2,4} grabbed 4 digits instead of stopping at 2. Every quantifier also has a lazy counterpart (written with a trailing ?, like *? or {2,4}?) that matches as little as possible instead — but that’s a big enough topic that it gets its own lesson shortly. For now, just remember: by default, more is preferred over less.

Try it yourself

Using the demo above, change the pattern from \d{2,4} to \d{2,4}? (add the lazy modifier) and see how the matches against "12345" change.

What should happen

With the lazy version, the match against "12345" becomes 12 instead of 1234 — the engine now stops as soon as the minimum (2 digits) is satisfied, rather than grabbing the maximum it’s allowed. Same pattern, same input, opposite strategy — that’s greedy vs. lazy in a nutshell, and you’ll dig into it properly in an upcoming lesson.

What’s next

Quantifiers so far have only applied to a single character or class. The next lesson introduces groups — parentheses (...) — which let you apply a quantifier to a whole sequence of characters at once, like (ab)+.

Quick check

What does a{2,4} match?

Which quantifier means "zero or one" of the preceding element?