代码之家  ›  专栏  ›  技术社区  ›  Dave Sag

有人能建议一个单行正则表达式用-或/分隔符来解析字母数字和可选的数字标识吗?

  •  1
  • Dave Sag  · 技术社区  · 6 年前

    我试图解析一组遵循以下模式的字符串

    {alpha-numeric-id}-{numeric-id}
    

    {alpha-numeric-id}/{numeric-id}
    
    1. alpha-numeric-id 可以包括 - 字符和数字
    2. 这个 numeric-id 始终是一个数字,并且是可选的。
    3. 这个 以及 数字id - /

    我想解析出 字母数字标识 (如果有)一步到位。

    'ThePixies1996' => { 1: 'ThePixies1996', 2: '' }
    '7ThePixies' => { 1: '7ThePixies', 2: '' }
    'The-Pixies' => { 1: 'The-Pixies', 2: '' }
    'The-Pixies-1234567' => { 1: 'The-Pixies', 2: '1234567' }
    'The-Pixies/1234567' => { 1: 'The-Pixies', 2: '1234567' }
    

    到目前为止,我想出的最简单的方法如下:

    const parse = str => {
      const numeric = str.match(/[-\/]([0-9]+)/)
    
      return numeric
        ? {
          numericId: numeric[1],
          alphaNumericId: str.slice(0, -1 * (numeric[1].length + 1))
        }
        : {
          numericId: '',
          alphaNumericId: str
        }
    }
    

    有更简单的方法吗?

    3 回复  |  直到 6 年前
        1
  •  0
  •   CertainPerformance    6 年前

    你可以用

    (.+?)(?:[\/-](\d+))?$
    

    https://regex101.com/r/PQSmaA/1/

    捕捉 alphaNumericId 在一个组中,通过懒洋洋地重复任何字符,然后可选地有一组破折号或正斜杠,后跟另一组中捕获的数字,即 numericId

    const input = ['ThePixies1996',
    '7ThePixies',
    'The-Pixies',
    'The-Pixies-1234567',
    'The-Pixies/1234567'
    ];
    function parse(str) {
      const [_, alphaNumericId, numericId = ''] = str.match(/(.+?)(?:[\/-](\d+))?$/);
      return { alphaNumericId, numericId };
    }
    console.log(
      input.map(parse)
    );

    假设输入总是有效的,比如 parse .

    const input = ['ThePixies1996',
    '7ThePixies',
    'The-Pixies',
    'The-Pixies-1234567',
    'The-Pixies/1234567',
    'invalid/input/string'
    ];
    function parse(str) {
       const match = str.match(/^([a-z\d-]+?)(?:[\/-](\d+))?$/i);
       if (!match) return 'INVALID';
       const [_, alphaNumericId, numericId = ''] = match;
      return { alphaNumericId, numericId };
    }
    console.log(
      input.map(parse)
    );
        2
  •  1
  •   revo shanwije    6 年前

    如果您知道要做什么,正则表达式会简单得多。尽管如此,这将是一个理想的解决办法:

    ^([\da-z-]+?)(?:[-/](\d+))?$
    

    说明:

    • ^ 匹配字符串开头
    • ([\da-z-]+?) - (不贪心)
    • (?:[-/](\d+))? 匹配以字符开头的字符串 - / 有选择地跟随一个数字序列(被捕获)的
    • $

    live demo

    var matches = [];
    'The-Pixies/12345'.replace(/^([\da-z-]+?)(?:[-/](\d+))?$/ig, function(m, $1, $2) {
        matches.push($1, $2);
    })
    
    console.log(matches.filter(Boolean));
        3
  •  0
  •   Amit    6 年前

    你可以不用regex用更简单的方法来做

    const parse = (data) => {
        let inx = data.lastIndexOf("-")
        if (inx === -1 || isNaN(data.slice(inx))){
            inx = data.lastIndexOf("/")  
        }
        return {
              numericId: data.slice(0, inx),
              alphaNumericId: data.slice(inx+1)
        }
    }