JavaScript字符串的exec方法表现奇怪

3

我在我的对象中有一个经常被调用的函数。

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 总是返回正确的结果?

2个回答

4

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

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

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

这是针对正则表达式字面量所描述的行为,让我引用规范:

§ 7.8.5 - 正则表达式字面量

...

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

....

您可以通过以下简单证明:

function createRe() {
  var re = /foo/g;
  return re;
}

createRe() === createRe(); // true, it's the same object

您可以确定这是同一个对象,因为"程序中的两个正则表达式字面量将被评估为正则表达式对象,即使这两个字面量的内容相同,它们也永远不会相互比较,即使使用 ===",例如:

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

然而,所有浏览器都遵循这种行为,但IE不会,它会每次初始化一个新的RegExp对象。

是的,我也怀疑是这样,但是为什么这些正则表达式变量没有被垃圾回收并重置呢?我认为每次调用parse()时,新的作用域都应该被初始化。 - Pablo

1
为避免这种行为,因为在这种情况下可能需要它,请简单地设置。
var r = /...pattern.../g;
var m = r.exec(html);
r.lastIndex=0;

这对我有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接