代码之家  ›  专栏  ›  技术社区  ›  Matus Dubrava

将模板文本内的正则表达式组捕获为函数参数

  •  1
  • Matus Dubrava  · 技术社区  · 8 年前

    我有一套一种格式的日期,我需要将这些日期转换成另一种格式。

    输入: <month>/<day>/<year>

    输出: <day>/<month>/<year> -此外,我还需要用 0 如果它只包含一个字符。

    我创建了正则表达式来匹配给定的日期格式。然后我想用 String.prototype.replace 并通过将捕获的组作为 replace 方法

    我面临的问题是,它没有像我预期的那样工作。在某些情况下,功能 pad 正确地填充日期,在其他情况下则不会。更准确地说,我希望第二个控制台日志是 12 ,但结果是 012

    const pad = date => date.length === 2 ? date : '0' + date;
    
    const normalizeDate = date => {
      const regex = /(?<month>\d{1,2})\/(?<day>\d{1,2})\/(?<year>\d{4})/;
    
      // pad string of length 1 works correctly (expected '01'/ result '01')
      console.log(date.replace(regex, `${pad('$<month>')}`));
    
      // pad sting of length 2 doesn't (expected '12' / result '012')
      console.log(date.replace(regex, `${pad('$<day>')}`));
    
      // test shows that <day> = 12
      console.log(date.replace(regex, `$<day>`));
    
      // padding 12 directly works (expected '12' / result '12') 
      console.log(pad('12'));
    
      return date.replace(regex, `${pad('$<month>')}-${pad('$<day>')}-$<year>`);
    }
    
    const date = '1/12/2014';
    normalizeDate(date);

    有人知道那个代码出了什么问题吗?

    1 回复  |  直到 8 年前
        1
  •  2
  •   Wiktor Stribiżew    8 年前

    这个 $<day> 命名的反向引用只能在字符串替换模式中使用。由于需要修改捕获,因此需要使用匿名方法:

    .replace(regex, (_,month,day,year) => `${pad(month)}`)
    

    这里,在括号中,您必须为整个匹配和捕获组定义变量。因此,基本上,您不需要新的ECMAScript 2018 regex增强功能,因为这里也可以使用常规编号的捕获组。

    查看更新的演示:

    const pad = date => date.length === 2 ? date : '0' + date;
    
    const normalizeDate = date => {
      const regex = /(?<month>\d{1,2})\/(?<day>\d{1,2})\/(?<year>\d{4})/;
    
      // pad string of length 1 works correctly (expected '01'/ result '01')
      console.log(date.replace(regex, (_,month,day,year) => pad(month)));
    
      // pad sting of length 2 doesn't (expected '12' / result '012')
      console.log(date.replace(regex, (_,month,day,year) => pad(day)));
    
      // test shows that <day> = 12
      console.log(date.replace(regex, "$<day>"));
    
      // padding 12 directly works (expected '12' / result '12') 
      console.log(pad('12'));
    
      return date.replace(regex, (_,month,day,year) => `${pad(month)}-${pad(day)}-${year}`);
    }
    
    const date = '1/12/2014';
    console.log(normalizeDate(date));