Med ECMAScript 2018 og med understøttelse i Chrome fra v. 64, Safari fra v. 11.1 og iOS Safari fra v. 11.3 er det blevet muligt at navngive grupper i RegExp i javascript.
Hidtil har det været muligt at hente værdier fra match-objektet med notationen $1, $2 … eller direkte matchObj[1], matchObj[2] … Hvis et simpelt CPR-mønster f.eks. anvendes, kan det se således ud:
const cprPattern = /([0-9]{2})([0-9]{2})([0-9]{2})-([0-9]{4})/; const match = "100688-2105".match(cprPattern); // eller // const match = cprPattern.exec("100688-2105"); if (match){ console.log(match[1]+'-'+match[2]+'-'+match[3]+ " ("+ match[4] + ")"); //10-06-88 (2105) }
Tibagereference, så udfaldet af en match-gruppe kan bruges senere i regex-mønstretm der søges på, kan ske med notationen \n hvor n er nummeret på match-gruppen
const cprPattern = /^([0-9]{2})([0-9]{2})([0-9]{2})-([0-9]{4}). Født (19|20)\3/; const match = "100688-2105. Født 1988".match(cprPattern); if (match){ console.log(match[1]+'-'+match[2]+'-'+match[3]+ " ("+ match[4] + ")"); //10-06-88 (2105) }
I string.replace er match-grupperne på tilsvarende vis tilgængelige med dollar-notationen $1, $2…
const cprPattern = /([0-9]{2})([0-9]{2})([0-9]{2})-([0-9]{4})/; console.log('100658-2105'.replace( cprPattern,`$1-$2-$3 ($4)` )); // 10-06-88 (2105)
Det har altsammen fungeret efter hensigten, men har haft nogle minusser. Dels er koden ikke særlig læsevenlig og dels kan f.eks. senere tilføjelse af gruppe rykke hele nummer-systemet.
Med ECMAScript 2018 er det muligt at navngive gruppe med formlen ?<gruppenavn> Ovenstående eksempel kan efterfølgende se ud som nedenstående. Match-objektet gemmer på et object groups med de tildelte gruppenavne:
const cprPattern = /(?<day>[0-9]{2})(?<month>[0-9]{2})(?<year>[0-9]{2})-(?<number>[0-9]{4})/; const match = "100688-2105".match(cprPattern); if (match){ const day = match.groups.day; const month = match.groups.month; const year = match.groups.year; const number = match.groups.number; console.log(`${day}-${month}-${year} (${number})`); //10-06-88 (2105) }
Med lidt dekonstruktion kan det gøres endnu enklere:
const cprPattern = /(?<day>[0-9]{2})(?<month>[0-9]{2})(?<year>[0-9]{2})-(?<number>[0-9]{4})/; const match = "100688-2105".match(cprPattern); if (match) { const {groups: {day, month, year, number}} = match; console.log(`${day}-${month}-${year} (${number})`); //10-06-88 (2105) }
Tilbage-referencer kan gøres mere læsevenlige med \k<gruppenavn>
const cprPattern = /(?<day>[0-9]{2})(?<month>[0-9]{2})(?<year>[0-9]{2})-(?<number>[0-9]{4}) Født (19|20)\k<year>/;
På samme måde kan gruppenavne anvendes i replace – enten direkte eller med replace-strengen som en funktion:
console.log('100688-2105'.replace( cprPattern,`$<day>-$<month>-$<year> ($<number>)` )); //10-06-88 (2105) console.log('100688-2105'.replace( cprPattern, (...args) => { const {day, month, year, number} = args[args.length-1]; return `${day}-${month}-${year} (${number})` })); //10-06-88 (2105)
Navngivning af grupper tilføjer således ikke i sig selv nye muligheder, ud over muligheden for at gøre koden mere logisk og læsevenlig. Men det er jo også noget.