首页 文章

为什么相同的RegExp表现不同? [重复]

提问于
浏览
12

可能重复:Javascript RegExp的有趣测试正则表达式测试无法在true和false之间做出决定(JavaScript)

Example of issue . 在内联运行时,结果如我所料 . 但是当存储为变量时,它会跳过中间 Span 元素 .

// Inline RegExp
function getToggleClasses() {
  var toggler = [],
      elements = document.getElementsByTagName("*"),
      i=0,
      len = elements.length;

  for (i; i < len; i++) {
    if (/toggler/g.test(elements[i].className)) {
      toggler.push(elements[i]);
    }
  }

  document.getElementById('results').innerHTML += "
Inline: " + toggler.length; } // Variable function getToggleClasses2() { var toggler = [], elements = document.getElementsByTagName("*"), tester = /toggler/g, i=0, len = elements.length; for (i; i < len; i++) { if (tester.test(elements[i].className)) { toggler.push(elements[i]); } } document.getElementById('results').innerHTML += "
Variable: " + toggler.length; } ​

标记:

<span class="toggler">A</span>
<span class="toggler">B</span>
<span class="toggler">C</span>

Given :我知道没有理由使用RegExp进行这种比较,我也理解jQuery这样的优秀库 . 我也知道在这种情况下不需要 g .

我无法理解为什么这两种方法应该返回不同的结果 .

3 回答

  • 9

    RegExp 实例是有状态的,因此重用它们可能会导致意外行为 . 在这种特殊情况下,这是因为实例是global,意思是:

    应该针对字符串中的所有可能匹配来测试正则表达式 .

    然而,这并不是使用 g 造成的唯一区别 . From RegExp.test @ MDN

    与exec(或与其结合使用)一样,在同一个全局正则表达式实例上多次调用的测试将超过上一个匹配 .


    Remove the g flag,或set lastIndex to 0(谢谢,@zzzzBov) .

  • 3

    不需要 /g ,在这种情况下不应使用 .

    在这些情况下,行为不同,因为在"inline"情况下,每次循环迭代都会重新创建正则表达式对象 . 而在变量中创建一次,并在循环迭代之间保持其状态(lastIndex) .

    将var移动到循环中,您将得到相同的结果:

    // Variable
    function getToggleClasses2() {
      var toggler = [],
          elements = document.getElementsByTagName("*"),
          i=0,
          len = elements.length;
    
      for (i; i < len; i++) {
        var tester = /toggler/g;
        if (tester.test(elements[i].className)) {
          toggler.push(elements[i]);
        }
      }
    
      document.getElementById('results').innerHTML += "
    Variable: " + toggler.length; }
  • 1

    正则表达式维护一个名为 lastIndex 的变量,该变量是开始下一次搜索的索引 . 来自MDN

    与exec(或与其结合使用)一样,在同一个全局正则表达式实例上多次调用的测试将超过上一个匹配 .

    为每次迭代定义内联正则表达式时,状态将丢失, lastIndex 始终为0,因为每次都有一个新的正则表达式 . 如果将正则表达式保持为可靠,则 lastIndex 将保存为最后一个匹配的结束位置,在这种情况下会导致下一个字符串结束时的下一个搜索开始,从而导致匹配失败 . 当第三次比较到来时, lastIndex 已被重置为0,因为正则表达式知道它上次没有结果 .

相关问题