W3docs

Capturing Groups

Learn capturing groups in JavaScript regular expressions: numbered groups, named groups, non-capturing groups, and how to extract matched text.

A capturing group is a part of a regular expression wrapped in parentheses (...). It does two things: it groups a piece of the pattern so quantifiers and alternation apply to the whole chunk, and it remembers the text that matched so you can read it back later.

This is what turns a regular expression from a yes/no test into a data-extraction tool. Instead of only knowing that a date matched, you can pull out the year, month, and day as separate pieces. This page covers numbered groups, named groups, non-capturing groups, and how groups behave with match, matchAll, and replace.

Understanding Capturing Groups

When a match is found, the whole match is stored at index 0 of the result array, and each capturing group is stored at the next indexes (1, 2, 3, …) in the order the groups' opening parentheses appear, left to right.

Syntax and Basic Usage

Here's a simple example:

javascript— editable

match[0] is always the entire matched string. match[1] and match[2] hold the text captured by the first and second sets of parentheses. The groups are numbered by their opening (, so even nested groups have a predictable order (see below).

Advanced Usage and Techniques

Nested Capturing Groups

Groups can be nested, allowing more complex pattern matching. The numbering follows each opening parenthesis from left to right:

javascript— editable

The outer group (group 1) captures foobar, while the inner groups (2 and 3) capture foo and bar separately. If a group is optional and doesn't participate in the match, its slot is undefined.

Non-Capturing Groups

Sometimes you want to group parts of a pattern — to apply a quantifier or alternation — without spending a numbered slot on it. Non-capturing groups use (?:...):

javascript— editable

Here foo is grouped but not captured, so bar becomes group 1 instead of group 2. Non-capturing groups keep your result array clean and are slightly faster when you don't need the matched text.

A common use is repeating a chunk without capturing every repetition:

javascript— editable

Practical Examples

Parsing Dates

Capturing groups can parse and reformat dates from strings:

javascript— editable

This code extracts the year, month, and day, then formats the date in a different style.

Extracting Information from URLs

Another common use case is extracting parts of a URL:

javascript— editable

This regular expression captures the protocol, domain, path, and query string separately.

Tips for Using Capturing Groups Effectively

  1. Plan Your Groups: Think ahead about what parts of the pattern you need to capture.
  2. Use Non-Capturing Groups When Needed: Use (?:...) for grouping without capturing to simplify your match array.
  3. Named Capturing Groups: In modern JavaScript (ES2018+), you can use named capturing groups for better readability.
  4. Global Flag Behavior: When using the g flag with String.prototype.match(), it returns an array of all matched strings instead of capturing groups. Use String.prototype.matchAll() for detailed group extraction with the global flag.

Named Capturing Groups

Numbered groups are fragile: add a group in the middle and every index after it shifts. Named capturing groups (ES2018+) avoid this by labeling each group with (?<name>...). The captures appear on a groups object instead of (or in addition to) numbered indexes:

javascript— editable
Info

Prefer named capturing groups for anything beyond a trivial pattern — they make both the regex and the code that reads it self-documenting.

Using Groups with match, matchAll, and replace

How you read out captured groups depends on the method you call.

Without the g flag — match returns groups

A non-global String.prototype.match() returns a single match array with all groups, exactly like the examples above. This is the most common way to extract a single record.

With the g flag — use matchAll for groups

When you add the global flag g, match() returns a flat array of full-match strings only — the groups are lost. To get groups for every match, use String.prototype.matchAll(), which returns an iterator of match arrays (each with its own groups object):

javascript— editable

Referring to groups in replace

In a String.prototype.replace() replacement string you can reference captures by number with $1, $2, … or by name with $<name>:

javascript— editable

For more control, pass a function to replace. Its arguments are the full match, then each captured group, and (if you used names) a final groups object:

javascript— editable

Backreferences

Once a group has captured text, you can match that same text again later in the same pattern using a backreference\\1 for numbered groups or \\k<name> for named ones. This is handy for finding repeated words or matching paired quotes:

javascript— editable

Backreferences are a topic of their own — see Backreferences in pattern for the full details.

Conclusion

Capturing groups in JavaScript regular expressions offer a robust way to work with complex string patterns. By mastering their use, you can perform sophisticated text manipulations, extract meaningful data, and handle replacements with ease. Whether you are parsing dates, processing URLs, or reformatting strings, capturing groups provide the flexibility and power needed for advanced text processing tasks. Explore these examples, practice with your own patterns, and enhance your JavaScript skills to handle any string manipulation challenge.

Practice

Practice
Which of the following statements about capturing groups in JavaScript regular expressions are true?
Which of the following statements about capturing groups in JavaScript regular expressions are true?
Was this page helpful?