Download Cheat sheet PDF 12 pages · syntax, editors, patterns, Unicode, performance, debugging
Concepts May 9, 2026

What does (?:) mean in regex? Non-capturing groups explained

Parentheses do two things in regex. (?:...) turns off the second one.

The short answer

(?:...) creates a non-capturing group. It groups the contents together (so a quantifier or alternation applies to the whole group) but does NOT save what was matched.

Compare:

(abc)+      grouping + capture — saves "abc" in group 1
(?:abc)+    grouping only — no group saved

What parentheses do — the two jobs

Regular parentheses do two things at once:

  1. Group — they tell the engine "this is one unit" so quantifiers apply to the whole group.
  2. Capture — they save what was matched as a numbered group, accessible later.

You always want job 1. Job 2 is only useful if you actually plan to read the captured value back. Non-capturing groups (?:...) let you opt out of job 2.

When you NEED non-capturing groups

1. When you don't want the noise in your capture results

If you're extracting some specific values:

Pattern: ^(?:\w+ ){2}(\w+)$
Input:   "Mary had a"
Captures: group 1 = "a"

The first group (?:\w+ ){2} is non-capturing — it groups so the {2} can repeat it, but doesn't pollute your capture list. The single capture group is (\w+), which gets a clean group-1 reference.

2. When alternation needs grouping

Bad:    cat|dog food         matches "cat" OR "dog food"
Good:   (?:cat|dog) food     matches "cat food" OR "dog food"

Without the group, the alternation extends to the whole pattern. The non-capturing group scopes it.

3. When you want to reuse a quantifier on a sub-pattern

(?:ab){3}    matches "ababab"
(?:\d{3}-){2}\d{4}    matches "123-456-7890

When non-capturing doesn't matter

If you don't care about captures and aren't referencing them, the difference between (abc) and (?:abc) is mostly stylistic. The non-capturing form:

  • Skips the work of saving the matched text
  • Makes intent clearer (you're telling the reader "I'm not capturing this")
  • Keeps numbered groups in order if you add captures later

For one-off scripts, this might be over-engineering. For library code or shared patterns, prefer (?:...) when you don't need the capture.

Named groups instead

Modern regex flavors support named groups, which are clearer than numbered ones:

JavaScript / PCRE:  (?<year>\d{4})
Python:             (?P<year>\d{4})

Match.groups.year    // JS
match.group("year")  # Python

Named groups still count toward group numbering. If you mix named and unnamed:

(?<area>\d{3})-(\d{3})-(\d{4})

groups: area, 2, 3

Or use non-capturing for the parts you don't want, named for the ones you do.

Performance — does (?:) speed things up?

Slightly. Capturing has some overhead (saving the match positions). For simple patterns this is negligible. For very hot loops on huge inputs, the difference might be measurable, but you're unlikely to notice.

The real reason to use (?:...) is clarity and capture-list cleanliness, not performance.

The takeaway

Use (?:...) when you need to group but don't need to capture. It keeps your capture list clean, makes intent explicit, and avoids renumbering surprises if you later add new captures.

For values you DO want to extract, prefer named groups (?<name>...) — they're self-documenting and don't break when patterns are reorganized.


Related reading


Try this pattern in the explainer

Paste any regex into the live explainer and see what each token means, with example matches in real time.

Open the regex explainer →