Home

Awesome

named-regexp-groups

Regular expressions with named capture groups and named back-references

NPM version Build Status

Create a named capture group with (?<name>.*) or (:<name>.*) when using a RegExp. The methods of RegExp are supported excluding compile and toString. Use named back-references using (?&name) to include already defined named pattern.

Installation

npm install --save named-regexp-groups

Usage

import NamedRegExp from 'named-regexp-groups'
//or
const NamedRegExp = require('named-regexp-groups')

// as string
var r = new NamedRegExp('(?<foo>foo)(?<bar>)(-)(?:wat)(?<na>(?:na)+)(?&na)')
// or as regex
var r = new NamedRegExp(/(:<foo>foo)(:<bar>)(-)(?:wat)(:<na>(?:na)+)(:&na)/)

r.source
// => r.source === '(foo)([^]+)(-)(?:wat)((?:na)+)((?:na)+)'

For nodejs < v5.0 core-js polyfills are required. Use npm i -S core-js in your project and add:

// for node < v0.11
require('core-js/es6/object')
// for node < v5.0
require('core-js/es6/string')
require('core-js/es6/symbol')

exec

var r = new NamedRegExp('(?<foo>foo)(?<bar>bar)(-)(?:wat)(?<na>(?:na)+)(?&na)')
r.exec('nanafoobar-watnana')
// => [ 'foobar-watnana', 'foo', 'bar', '-', 'na', 'na',
//  index: 4,
//  input: 'nanafoobar-watnana',
//  groups: { foo: 'foo', bar: 'bar', '0': '-', na: 'na', '1': 'na' } ]

test

r = new NamedRegExp('(?<foo>foo)(bar)(?:waah)')
r.source
// => '(foo)(bar)(?:waah)'
r.test('nanafoobarwaah')
// => true

String.replace

If using a string as replacement use $+{name} to define the placeholder for the capture group. This follows the Syntax of PCRE Named backreferences.

var r = new NamedRegExp(/(:<year>\d+)-(:<month>\d+)-(:<day>\d+)/)

// ---- using strings
'2017-01-02'.replace(r, 'day: $+{day}, month: $+{month}, year: $+{year}')
// => 'day: 02, month: 01, year: 2017')

// ---- using function
'2016-11-22'.replace(r, function () { // take care of NOT using an arrow function here!
  var args = [].slice.call(arguments)
  var g = this.groups
  return `day: ${args[g.day]}, month: ${args[g.month]}, year: ${args[g.year]}`
})
// => 'day: 22, month: 11, year: 2017')

String.match

r = new NamedRegExp('(?<foo>foo)(bar)(?:waah)')
'nanafoobarwaah'.match(r)
// => [ 'foobarwaah', 'foo', 'bar',
//      index: 4, input: 'nanafoobarwaah',
//      groups: { '0': 'bar', foo: 'foo' } ]

String.split

r = new NamedRegExp('(?<foo>foo)')
'nanafoobarwaah'.split(r)
// => [ 'nana', 'foo', 'barwaah' ]

ES7

The proposed TC39 proposal-regexp-named-groups is finding it's way into the standard. Chrome>=64 already supports named groups. Maybe node>=10 soon as well...

Paste this into Chrome>=64

r = new RegExp(/(?<foo>foo)(?<bar>bar)(-)(?:wat)(?<na>(?:na)+)/);
o = r.exec('nanafoobar-watnana')
//> (5) ["foobar-watnana", "foo", "bar", "-", "na",
//>  index: 4, input: "nanafoobar-watnana",
//>  groups: {foo: "foo", bar: "bar", na: "nana"}]

License

Software is released under MIT.