Regular Expressions: Capturing Groups

Join the AI Workshop to learn more about AI and how it can be applied to web development. Next cohort February 1st, 2026

The AI-first Web Development BOOTCAMP cohort starts February 24th, 2026. 10 weeks of intensive training and hands-on projects.


So far, we’ve seen how to test strings and check if they contain a certain pattern.

A very cool feature of regular expressions is the ability to capture parts of a string, and put them into an array.

You can do so using Groups, and in particular Capturing Groups.

By default, a Group is a Capturing Group. Now, instead of using RegExp.test(String), which just returns a boolean if the pattern is satisfied, we use one of

  • String.match(RegExp)
  • RegExp.exec(String)

They are exactly the same, and return an Array with the whole matched string in the first item, then each matched group content.

If there is no match, it returns null:

'123s'.match(/^(\d{3})(\w+)$/)
//Array [ "123s", "123", "s" ]

/^(\d{3})(\w+)$/.exec('123s')
//Array [ "123s", "123", "s" ]

'hey'.match(/(hey|ho)/)
//Array [ "hey", "hey" ]

/(hey|ho)/.exec('hey')
//Array [ "hey", "hey" ]

/(hey|ho)/.exec('ha!')
//null

When a group is matched multiple times, only the last match is put in the result array:

'123456789'.match(/(\d)+/)
//Array [ "123456789", "9" ]

Optional groups

A capturing group can be made optional by using (...)?. If it’s not found, the resulting array slot will contain undefined:

/^(\d{3})(\s)?(\w+)$/.exec('123 s') //Array [ "123 s", "123", " ", "s" ]
/^(\d{3})(\s)?(\w+)$/.exec('123s') //Array [ "123s", "123", undefined, "s" ]

Reference matched groups

Every group that’s matched is assigned a number. $1 refers to the first, $2 to the second, and so on. This will be useful when we’ll later talk about replacing parts of a string.

Named Capturing Groups

A group can be assigned to a name, rather than just being assigned a slot in the result array:

const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
const result = re.exec('2015-01-02')

// result.groups.year === '2015';
// result.groups.month === '01';
// result.groups.day === '02';

Lessons in this unit:

0: Introduction
1: Introduction
2: Anchoring
3: Match Items in Ranges
4: Matching a Range Item Multiple Times
5: Negating a Pattern
6: Meta Characters
7: Regular Expressions Choices
8: Quantifiers
9: Optional Items
10: Groups
11: ▶︎ Capturing Groups
12: Using match and exec Without Groups
13: Noncapturing Groups
14: Flags
15: Inspecting a Regex
16: Escaping
17: String Boundaries
18: Replacing
19: Greediness
20: Lookaheads
21: Lookbehinds
22: Unicode
23: Unicode Property Escapes
24: Examples