Concept

Capturing Groups and Non-Capturing Groups

Parentheses group tokens and capture the matched substring. (?:...) groups without capturing — use it when you want grouping for quantifiers or alternation but don't need the submatch.

Capturing groups

Parentheses create a capturing group — the substring matched by the group is accessible as a numbered submatch (group 1, 2, 3 ...). In JavaScript, String.match returns them in the array; in replacements, $1 and $2 reference them.

Capture year and month

Try this
/(\d{4})-(\d{2})/

Input

2026-04

Result

Full: 2026-04, Group 1: 2026, Group 2: 04

Non-capturing groups (?:...)

A leading ?: inside the parens makes the group non-capturing. Same grouping for quantifiers and alternation, but no submatch is stored. Useful when you want (foo|bar) to alternate but don't care about which one matched.

Non-capturing alternation

Try this
/(?:jpg|jpeg|png|gif)$/

Input

photo.jpeg

Result

Match: jpeg (no capture group exposed)

Why non-capturing matters

Two reasons. Performance — capturing has overhead on large inputs and in replacement pipelines. Clarity — if you're not using the submatch, non-capturing signals intent and keeps $1/$2 aligned with the groups you actually care about.

Named groups

Modern JavaScript (ES2018+) supports named groups: (?<year>\d{4}). Access them via match.groups.year instead of match[1]. Named groups make backreferences and replacements self-documenting — $<year> in a replacement is clearer than $1.

Related patterns

All reference guidesOpen the RegexPro tester →