Grouping and Back References

During replacements, within a match, you can group the characters with (), and back-reference them with $1-$9.

Additionally, $& references the whole match.
$` references the left context.
$' references the right context.


var s = "abc";
console.log(s.replace(/a(.)(.)/, "$2"));
console.log(s.replace(/a/, "$&$&"));
console.log(s.replace(/b/, "$`"));
console.log(s.replace(/a/, "$'"));

c aabc aac bcbc

You can name each capture group by starting the () group with ?<name>.


const r = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u;
const d = r.exec("2020-07-29");
/*
d.groups.year === "2020"
d.groups.month === "07"
d.groups.day === "29"
d[0] === "2020-07-29"
d[1] === "2020"
d[2] === "07"
d[3] === "29"
*/
let { groups: { year, month, day } } = d;  // destructuring
console.log(year, month, day);

2020 07 29

Before ECMAScript 2025, the same named group could not appear twice in one pattern, even in alternatives (branches separated by |) that can never both match at once. ECMAScript 2025 permits duplicate named capture groups as long as, for every possible match, at most one branch defining that name can actually participate — a common shape when a date, for instance, may be written in more than one format.


const r = /^(?:(?<year>\d{4})-(?<month>\d{2})|(?<month>\d{2})\/(?<year>\d{4}))$/;
console.log(r.exec('2020-07').groups);
console.log(r.exec('07/2020').groups);

{year: '2020', month: '07'} {year: '2020', month: '07'}