Google Sheets iconSwift icon
Published at
Updated at
Reading time
2min

This post is part of my Today I learned series in which I share all my learnings regarding web development.

It's regular expression time again. 🎉 I don't remember where I saw the following discovery, but I'm astonished that I didn't know about non-capturing groups after years of using regular expressions.

To understand how non-capturing groups work, let's look at an example highlighting the well-known capturing groups.

// a regular expression including three capture groups
const regex = /(Jane|John|Alison)\s(.*?)\s(Smith|Smuth)/;

The regular expression above defines that I'm looking for a very particular name combination. The name should begin with Jane, John or Alison, end with Smith or Smuth but include characters for a middle name in between the first and last name.

const result = regex.exec('Jane Isabell Smith');
console.log(result[0]); // 'Jane Isabell Smith'
console.log(result[1]); // 'Jane'
console.log(result[2]); // 'Isabell'
console.log(result[3]); // 'Smith'

Run the regular expression's exec method to test if a string is matching the expression. If the string matches the expression, the return value is an array holding all the specific information, otherwise exec returns null.

The array includes the full matching string at index 0 followed by the defined groups (1, 2, etc.). In this example, the array holds the character sequences matching the three defined capturing groups. Even though you're only interested in the middle name represented by the entry at index 2 you have to deal with the data for all groups.

There's nothing particularly wrong with this approach, but to extract the desired middle name you have to remember and go back to the original regular expression because the result includes several irrelevant values (1 and 3).

It turns out that you can define non-capturing groups that are not included in the result!

// a regular expression with two non-capturing groups
// and one capturing group
const regex = /(?:Jane|John|Alison)\s(.*?)\s(?:Smith|Smuth)/;
const result = regex.exec('Jane Isabell Smith');
console.log(result[0]); // 'Jane Isabell Smith'
console.log(result[1]); // 'Isabell'

const notMatchingResult = regex.exec('nope');
console.log(notMatchingResult); // null

Use the (?:) syntax to match non-capturing groups in your strings. Non-capturing groups are excluded from the result.

When dealing with complex regular expressions, this feature is beneficial because it simplifies the result handling! 🎉

Edited: As Dave Newson pointed out, there are also named capture groups on their way! The "group future" looks bright!

Related Topics

Related Articles