【问题标题】:Overlapping named capturing groups重叠命名的捕获组
【发布时间】:2019-04-27 12:13:13
【问题描述】:

我正在使用命名捕获组来验证和提取产品编号中的数据。产品编号的格式如下:

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

我当前的代码如下所示:

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)

由于gender_codestyle 重叠,我不确定如何同时获得它们。因此我有以下问题:

  1. 是否可以只使用一个正则表达式?
  2. 如果是,我该如何做到这一点?

【问题讨论】:

    标签: javascript regex validation named-captures


    【解决方案1】:

    当然,只需将gender 放在style 组中:

    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)

    【讨论】:

      【解决方案2】:

      我建议只为前两个和四个后续字符设置单独的捕获组。然后,通过将前两个捕获组连接在一起形成style

      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]);

      作为一种风格说明,我不喜欢使用命名捕获组,因为它们往往会导致正则表达式臃肿而难以阅读。

      【讨论】:

        【解决方案3】:

        是的,您可以使用此正则表达式通过正面展望来捕获性别代码,

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

        Regex Demo

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

        命名的捕获分组将在 ECMAScript 2018 中可用,目前仅在 Chrome 中受支持。

        这个 JS 演示将在 Chrome 中运行,因为它是目前唯一支持 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)

        【讨论】:

        • 感谢您指出命名捕获组目前并非在每个浏览器中都有效。因为我们这个函数只在 Node.js v10 环境中使用,所以没关系:-)
        • 如果要在 Node.js 中使用,那么您可以在我的第二个 regex101 演示中使用该正则表达式。效果很好。
        猜你喜欢
        • 1970-01-01
        • 2011-07-27
        • 2014-06-26
        • 1970-01-01
        • 2014-09-11
        • 1970-01-01
        • 2023-04-03
        • 1970-01-01
        相关资源
        最近更新 更多