Code of the Day
BeginnerCore syntax

Quantifiers

Control how many times an element must appear — from optional to unlimited — and understand the greedy vs lazy distinction.

Regular ExpressionsBeginner10 min read
Recommended first
By the end of this lesson you will be able to:
  • Apply *, +, ?, {n}, {n,}, and {n,m} correctly
  • Predict whether a greedy quantifier will match more or fewer characters
  • Convert a greedy quantifier to lazy with ?

A quantifier tells the engine how many times the preceding atom — a single character, a shorthand class, or a group — must appear. Without quantifiers you can only match fixed-length text. With them you can match "one or more digits," "zero or one space," or "exactly three uppercase letters."

The six quantifiers

QuantifierMeaningExampleMatches
*0 or more/\d*/"", "5", "42", "1000"
+1 or more/\d+/"5", "42", "1000"
?0 or 1/colou?r/"color", "colour"
{n}Exactly n/\d{4}/"2024"
{n,}n or more/\d{2,}/"12", "345", "1000"
{n,m}Between n and m/\d{2,4}/"12", "123", "1234"

* — zero or more

* matches the preceding atom any number of times, including zero. It is useful when something might or might not be present:

/go*d/.test("gd");     // true — zero 'o's
/go*d/.test("god");    // true — one 'o'
/go*d/.test("good");   // true — two 'o's

+ — one or more

+ requires at least one match. It is the most common quantifier because "at least one" captures the usual meaning of "a number," "a word," etc.:

/\d+/.test("abc");     // false — no digits at all
/\d+/.test("abc1");    // true  — found '1'
/\d+/.test("abc123");  // true  — found '123'

? — optional

? makes the preceding atom optional (zero or one occurrence):

/https?:\/\//.test("http://example.com");   // true — no 's'
/https?:\/\//.test("https://example.com");  // true — with 's'

The pattern /colou?r/ matches both British and American spelling because u is optional.

{n} — exact count

/\b\d{4}\b/.test("year 2024");   // true — exactly four digits
/\b\d{4}\b/.test("year 24");     // false — only two digits

\b in the examples above is a word boundary anchor (covered in the next lesson). Here it just prevents /\d{4}/ from matching the first four digits of a longer number like 12345.

{n,} — at least n

/\w{5,}/.test("hi");        // false — only 2 characters
/\w{5,}/.test("hello");     // true  — exactly 5
/\w{5,}/.test("excellent"); // true  — 9 characters

{n,m} — bounded range

/\d{2,4}/.test("1");       // false — only 1 digit
/\d{2,4}/.test("12");      // true  — 2 digits
/\d{2,4}/.test("12345");   // true  — matches first 4

Note the last example: the engine matches as many as the upper bound allows inside the string; it does not require the whole string to be that length.

Greedy vs lazy

By default, quantifiers are greedy — they consume as many characters as possible while still allowing the overall pattern to match:

const html = "<b>hello</b> and <b>world</b>";
const m = html.match(/<.+>/);
console.log(m[0]); // "<b>hello</b> and <b>world</b>"

The + expanded as far as possible, swallowing both tags and everything between them. That is usually not what you want when matching HTML-like content.

Adding ? after a quantifier makes it lazy — it matches as few characters as possible:

const html = "<b>hello</b> and <b>world</b>";
const m = html.match(/<.+?>/);
console.log(m[0]); // "<b>"

Now +? stops at the first > it finds.

GreedyLazyBehaviour
**?As few as possible (0 preferred)
++?As few as possible (1 minimum)
???As few as possible (0 preferred)
{n,m}{n,m}?As few as possible within range

Lazy quantifiers are not always faster. In some patterns they cause the engine to backtrack extensively. If you find yourself depending on greedy-vs-lazy to fix a pattern, often a more precise character class is the cleaner solution: [^>]+ instead of .+? when matching content that should stop at >.

Common mistakes

Forgetting that * allows zero matches. /\d*\.csv/ matches ".csv" because \d* can match zero digits. Use \d+ if at least one digit is required.

Applying a quantifier to the wrong atom. In /ab+/, the + applies only to b, not to ab. To repeat the pair, use a group: /(ab)+/.

JavaScript — editable, runs in your browser

Where to go next

Next: anchors^, $, and \b nail a pattern to a specific position in the string rather than letting it float anywhere.

Finished reading? Mark it complete to track your progress.

On this page