【问题标题】:javascript string exec strange behaviorjavascript字符串执行奇怪的行为
【发布时间】:2010-05-11 02:17:42
【问题描述】:

在我的对象中有定期调用的功能。

parse : function(html)
{
    var regexp = /...some pattern.../
    var match = regexp.exec(html);
    while (match != null)
    {
        ...
        match = regexp.exec(html);
    }
    ...
    var r = /...pattern.../g;
    var m = r.exec(html);
}

在 html 不变的情况下,m 在相互调用时返回 null。比方说

parse(html);// ok
parse(html);// m is null!!!
parse(html);// ok
parse(html);// m is null!!!
// ...and so on...

html 上是否有任何必须重置的索引或问题...我真的很困惑。为什么match 总是返回正确的结果?

【问题讨论】:

    标签: javascript regex string exec


    【解决方案1】:

    当您处理具有全局 g 标志的模式并使用 exectest 方法时,这是一种常见的行为。

    在这种情况下,RegExp 对象将跟踪找到匹配项的 lastIndex,然后在后续匹配项中,它将从该 lastIndex 开始,而不是从 0 开始。

    编辑:针对您的评论,为什么在您再次调用该函数时不会重新创建 RegExp 对象

    这是正则表达式文字描述的行为,让我引用规范:

    § 7.8.5 - Regular Expression Literals

    ...

    对象是在包含程序或函数的评估开始之前创建的。对文字的求值会产生对该对象的引用;它不会创建新对象。

    ....

    你可以做一个简单的证明:

    function createRe() {
      var re = /foo/g;
      return re;
    }
    
    createRe() === createRe(); // true, it's the same object
    

    您可以确定这是同一个对象,因为 “程序中的两个正则表达式文字计算为正则表达式对象,即使两个文字的内容相同,它们也不会相互比较为 ===,例如:

    /foo/ === /foo/; // always false...
    

    然而,这种行为在所有浏览器上都受到尊重,但 IE 却没有,它每次都会初始化一个新的 RegExp 对象。

    【讨论】:

    • 是的,我一直在怀疑类似的事情,但是为什么那些正则表达式变量没有经过 gc-ed 并被重置?我相信每次调用 parse() 时都应该初始化新的作用域。
    【解决方案2】:

    为避免这种情况下可能需要的行为,只需设置

    var r = /...pattern.../g;
    var m = r.exec(html);
    r.lastIndex=0;
    

    这对我有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-27
      • 1970-01-01
      • 2023-03-20
      相关资源
      最近更新 更多