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-04Result
Full: 2026-04, Group 1: 2026, Group 2: 04Non-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.jpegResult
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
HTML Tag Matcher
Match paired HTML tags and capture the tag name and inner content using a back-reference.
/<([a-zA-Z][a-zA-Z0-9]*)\b[^>]*>([\…/gMarkdown Link
Match Markdown links [link text](url) and capture both the display text and the URL.
/\[([^\]]+)\]\(([^)]+)\)/gMarkdown Heading
Matches markdown ATX-style headings (# through ######).
/^(#{1,6})\s+(.+)$/gmISO 8601 Date
Match dates in ISO 8601 format: YYYY-MM-DD with valid month (01–12) and day (01–31) ranges.
/\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|…/g