Capturing Groups

As we have seen before, parentheses can be used to group expressions together. Capturing groups are a special kind of group that capture their matched text. This allows extracting information from matches later.

Here is an example where a Pomsky expression is used to match a semantic version number:

# a semver version number, e.g. '1.3.17'
:([digit]+) '.' :([digit]+) '.' :([digit]+)

The : in front of the groups turns them into capturing groups. This means that when matching the string 1.3.17, the regex engine will create 3 captures containing the substrings 1, 3, and 17.

Here is how we could use them in JavaScript:

import versionRegex from './versionRegex.pom'

function createVersionTag(version) {
  return version.replace(versionRegex(), 'v$1_$2_$3')
}

The import statement imports and compiles the Pomsky expression, which is expected to be in another file, versionRegex.pom.

The replace function accepts two arguments: The compiled Pomsky expression, and a substitution string. This string contains some placeholders, $1, $2, and $3, which are substituted with the 1st, 2nd, and 3rd capturing group. So when the function is called with '1.3.17', it will return v1_3_17.

Named capturing groups

You can give capturing groups a name:

:major([digit]+) '.' :minor([digit]+) '.' :patch([digit]+)

This is good practice, as you no longer need to count capturing groups and can simply refer to them by their name:

import versionRegex from './versionRegex.pom'

function createVersionTag(version) {
  const { major, minor, patch } = versionRegex().exec(version).groups
  return `v${major}_${minor}_${patch}`
}