Overlapping named capturing groups

84 Views Asked by At

I'm using named capturing groups to validate and extract data out of a product number. The format of the product number looks like this:

1102961D048.075

Chars 1-2     gender_code   11
Chars 1-6     style         110296
Chars 7-8     width_code    1D
Chars 9-11    color_code    048
Char  12      delimiter     ignored
Chars 13-15   size_code     075

My current code looks like this:

const validateMpn = (mpn) => {
  const regex = /(?<style>\d{6})(?<width>\d{1}[ABDE])(?<color_code>\d{3})\.(?<size_code>\d{3})/gi
  const match = regex.exec(mpn)

  if (!match) {
    return null
  }

  return match.groups
}

const str1 = '1102961D048.075'
const str2 = '1200322A001.085'
const match1  = validateMpn(str1)
const match2  = validateMpn(str2)

console.log(match1)
console.log(match2)

As gender_code and style overlap I'm not sure how to get them both. Therefore I have the following questions:

  1. Is it possible to this with only one regular expression?
  2. If yes, how could I accomplish this?
3

There are 3 best solutions below

0
On BEST ANSWER

Sure, just place gender inside the style group:

const validateMpn = (mpn) => {
  const regex = /(?<style>(?<gender>\d{2})\d{4})(?<width>\d{1}[ABDE])(?<color_code>\d{3})\.(?<size_code>\d{3})/gi
  const match = regex.exec(mpn)

  if (!match) {
    return null
  }

  return match.groups
}

const str1 = '1102961D048.075'
const str2 = '1200322A001.085'
const match1  = validateMpn(str1)
const match2  = validateMpn(str2)

console.log(match1)
console.log(match2)

0
On

I suggest just having separate capture groups for the first two and four following characters. Then, form the style by just concatenating together the first two capture groups:

var input = "1102961D048.075";
var regex = /(.{2})(.{4})(.{2})(.{3}).(.{3})/g;
var match = regex.exec(input);
console.log("gender_code: " + match[1]);
console.log("style: " + match[1] + match[2]);

As a style note, I prefer not using named capture groups, because they tend to result in a bloated regex which is hard to read.

2
On

Yes you can capture gender_code using positive look ahead using this regex,

(?=(..))(\d{6})(\d{1}[ABDE])(\d{3})\.(\d{3})

Regex Demo

This is named groups regex but will only work in Chrome browser

and named capture grouping will be available in ECMAScript 2018 and is only supported in Chrome as of now.

This JS demo will work in Chrome as that is the only one as of now supporting EcmaScript2018,

const validateMpn = (mpn) => {
  const regex = /(?=(?<gender_code>\d\d))(?<style>\d{6})(?<width>\d{1}[ABDE])(?<color_code>\d{3})\.(?<size_code>\d{3})/gi
  const match = regex.exec(mpn)

  if (!match) {
    return null
  }

  return match.groups
}

const str1 = '1102961D048.075'
const str2 = '1200322A001.085'
const match1  = validateMpn(str1)
const match2  = validateMpn(str2)

console.log(match1)
console.log(match2)