Categories
Modern JavaScript

Best Features of ES2018 — Regex

Spread the love

Since 2015, JavaScript has improved immensely.

It’s much more pleasant to use it now than ever.

In this article, we’ll look at the best features of ES2018.

Numbered Capture Groups

Numbered capture groups lets us take apart a string with a regex.

This is the old way to get group matches.

A regex that matches a string returns a matched object.

Then we can get each part by its index.,

For instance, we can write:

const PHONE_REGEX = /([0-9]{3})-([0-9]{3})-([0-9]{4})/;

const matchObj = PHONE_REGEX.exec('123-456-7890');

We have 3 capture groups. 2 with 3 digits and one with 4 digits.

Then we can get each group by its index.

The problem with named capture groups is that we’ve to count parentheses.

We’ve to know what the groups are about from the regex pattern.

And we’ve to change the code if we change the regex.

Named Capture Groups

ES2018 gives us a new way to get a group match.

For instance, we can write:

const PHONE_REGEX = /(?<areaCode>[0-9]{3})-(?<officeCode>[0-9]{3})-(?<number>[0-9]{4})/;

const matchObj = PHONE_REGEX.exec('123-456-7890');
console.log(matchObj.groups)

We added the names to the groups.

Then we can get the matches in the groups property.

So we’ll get:

{ areaCode: "123", officeCode: "456", number: "7890" }

as the value of macthObj.groups .

This means that we can destructure the matches:

const PHONE_REGEX = /(?<areaCode>[0-9]{3})-(?<officeCode>[0-9]{3})-(?<number>[0-9]{4})/;

const matchObj = PHONE_REGEX.exec('123-456-7890');
const {
  areaCode,
  officeCode,
  number
} = matchObj.groups;

Named captured groups are good because it’s easier to identify the capture group.

The matching code is descriptive since the ID describes what it’s capturing.

And we can change the pattern without changing the matching code.

The names make the pattern easier to understand.

Backreferences

We can reference a matching group by its name in a regex.

For instance, we can write:

const REGEX = /^(?<word>[abc]+)k<word>$/;

const matchObj = REGEX.exec('abcabc');
console.log(matchObj.groups)

Then get the matches with marchObj.groups.words .

word has the same pattern.

replace()

We can use replace with named capture groups.

For instance, we can write:

const PHONE_REGEX = /(?<areaCode>[0-9]{3})-(?<officeCode>[0-9]{3})-(?<number>[0-9]{4})/;

console.log('123-456-7890'.replace(PHONE_REGEX,
  '$<areaCode>$<officeCode>$<number>'))

We called replace with our regex and a string with the pattern that we want to format the string to.

We just get the named capture groups and combined them without spaces.

So we get:

'1234567890'

returned.

It also takes a callback that has the groups as one of the parameters:

const PHONE_REGEX = /(?<areaCode>[0-9]{3})-(?<officeCode>[0-9]{3})-(?<number>[0-9]{4})/;

console.log('123-456-7890'.replace(PHONE_REGEX,
  (g0, ac, oc, num, offset, input, {
    areaCode,
    officeCode,
    number
  }) => `${areaCode}${officeCode}${number}`))

The last parameter has the groups.

Also, ac , oc , and num are the groups.

We return a new string so that it’ll be the string returned by replace .

g0 has the full string.

offset specifies where the matches are found.

input has the complete input string.

Named groups that don’t match

If we have named groups that don’t match, then the property will be undefined in the groups property.

Conclusion

Named capture groups are handy for naming matches so we can understand them easier and won’t have to change the matching code.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *