Non-capturing groups in regular expressions

2 min read

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 after years of using regular expressions, I'm very surprised that I haven't seen it before.

Let's have a look at an example showing capturing groups.

const regex = /(Jane|John|Alison)\s(.*?)\s(Smith|Smuth)/;

The regex 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 also have a middle 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'

The by exec returned array holds the full string of characters matched followed by the defined groups. Now, to get the middle name, I'd have to look at the regular expression to find out that it is the second group in the regex and will be available at result[2].

There's nothing particularly wrong with this but groups I'm not interested in are included in the result which makes it a bit more difficult for me deal with the returned value.

It turns out that you can define groups that are not captured!

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'

You can use (?:) to not capture groups and drop them from the result. When you're dealing with complex regular expressions this can be indeed very helpful! 🎉

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

Load time