Explain Codes LogoExplain Codes Logo

How do you access the matched groups in a JavaScript regular expression?

javascript
matchall
regex
javascript-regex
Alex KataevbyAlex Kataev·Dec 12, 2024
TLDR

Access regex groups using the .exec() or .match() methods as shown below:

const regex = /(\w+) (\w+)/; // RegEx pattern capture groups in parentheses const str = "Hello World"; const [_, firstWord, secondWord] = regex.exec(str) || [];

Here firstWord equals "Hello", and secondWord equals "World". Use parentheses () in your pattern to create capture groups.

Working with multiple matches: Meet matchAll

When your string contains multiple, repeating patterns, String.prototype.matchAll() is invaluable. It returns an iterator for all matches, which you can easily turn into an array using spread syntax:

const regex = /(\w+)/g; // the "g" flag means global, we're searching the WHOLE string const str = "Hello World 2023"; // it's a phrase from the future 😉 const matches = [...str.matchAll(regex)]; // matches is now an array of all matches! matches.forEach(([_, word]) => console.log(word)); // impress your friends with fancy destructuring!

Remember, index 1 onwards contains your capturing groups.

Utilising capture groups: Tips and tricks

The power of matchAll

matchAll is a Swiss Army knife. It does the job neatly and handles side effects on the regex's lastIndex property, which is altered when the regex is executed with a "g" flag.

const pattern = /(\w+)\s/g; // that "g" flag is not for decoration const phrase = "Coding is fun"; // some say it's the new rock and roll for (const [_, word] of phrase.matchAll(pattern)) { console.log(word); // blast off with "Coding" and "is", fun didn't make it to the console }

Remember, always use the global flag g to prevent the infinite loop that matchAll may cause!

Replace meets capturing groups

The replace() method with a callback function is an alternative way to work with capture groups. It's like inviting a friend to help.

const pattern = /(\w+)\s/g; // back at it with our global friend "g" const phrase = "Coding is fun"; // we promise it's not false advertising const words = []; // an empty home for words phrase.replace(pattern, (_, word) => { words.push(word); // inviting each word to hang out in our array }); console.log(words); // ["Coding", "is"], do we have room for "fun"?

This might not replace the initial string but it sure does replace your worries with match capturing!

Handling no matches with match

JavaScript can get dramatic and return null for no matches. Here's a way to keep it under control:

const matches = str.match(/pattern/) || []; // fallback to empty array, like a safety airbag

Advanced group matching techniques

Non-capturing groups and word boundaries

Non-capturing groups (?:...) and word boundaries \b can polish your regex skills to wow even the most seasoned developers.

const pattern = /(?:\w+\s){2}(\w+)/; // we're only interested in the third word const str = "Welcome to Paradise"; const match = pattern.exec(str); console.log(match[1]); // prints "Paradise", we're on vacation!

Remember, non-capturing groups organize your pattern but don't return captured groups.

Cleaner manipulation with arrow functions

Manipulating matches gets prettier with ES6 arrow functions:

const pattern = /\b(\w+)\b/g; const sentence = "JS is cool"; // and it's cooler with arrow functions const wordsUpper = Array.from(sentence.matchAll(pattern), ([_, w]) => w.toUpperCase());

Ain't that a classy way to convert all words to uppercase!

Replace to the extraction rescue

const info = "Name: John, Age: 30"; const regex = /Name: (\w+), Age: (\d+)/; let name, age; info.replace(regex, (_, n, a) => { name = n; // saving "John" for later age = a; // knowing John's age, don't tell anyone }); console.log(name, age); // prints John 30, but remember, this stays between us