代码之家  ›  专栏  ›  技术社区  ›  Jatin Sanghvi

RegExp.protype.exec()可以永远循环

  •  0
  • Jatin Sanghvi  · 技术社区  · 2 年前

    复制步骤:

    这将导致一个无限循环。如何防止这种情况发生?在我的Node应用程序中,用户可以指定 .* 作为图案,它悬挂着。我认为进行字符串匹配并阻止这种特定的regex模式不会有帮助,因为可能还有许多其他模式会导致无限循环。

    源代码(如果MDN页面的内容发生更改):

    const regex1 = RegExp('.*', 'g');
    const str1 = 'text';
    let array1;
    
    while ((array1 = regex1.exec(str1)) !== null) {
      console.log(array1.index);
    }
    
    2 回复  |  直到 2 年前
        1
  •  1
  •   Bergi    2 年前

    所有可以匹配空字符串的模式都表现出这种行为-请参阅 Regex that can match empty string is breaking the javascript regex engine Zero-Length regexes and infinite matches? .

    简单的解决方案是使用 matchAll 相反 testing for some complicated loop condition 你自己

    const regex = /.*/g;
    const str = 'text';
    for (const match of str.matchAll(regex)) {
      console.log(match.index, match[0]);
    }

    或者,使用 str.match(regex) 而不是 regex.exec(str) 也会有所帮助。

        2
  •  1
  •   Nick    2 年前

    你可以添加一个检查 lastIndex regex的属性已经更改,如果它没有更改(表示长度为零的匹配,然后将无限循环),则中断循环:

    const regex1 = RegExp('.*', 'g');
    const str1 = 'text';
    let array1;
    let lastIndex = 0;
    
    while ((array1 = regex1.exec(str1)) !== null) {
      console.log(array1);
      if (regex1.lastIndex == lastIndex) break;
      lastIndex = regex1.lastIndex;
    }

    注意,你可以在做任何事情之前进行测试,结果是 exec ,这取决于是否要捕获零长度匹配。