在 Chrome 或 Firebug 控制台中:
reg = /ab/g
str = "abc"
reg.exec(str)
==> ["ab"]
reg.exec(str)
==> null
reg.exec(str)
==> ["ab"]
reg.exec(str)
==> null
exec 是否有状态并取决于它上一次返回的内容?或者这只是一个错误?我不能让它一直发生。例如,如果上面的“str”是“abc abc”,它就不会发生。
在 Chrome 或 Firebug 控制台中:
reg = /ab/g
str = "abc"
reg.exec(str)
==> ["ab"]
reg.exec(str)
==> null
reg.exec(str)
==> ["ab"]
reg.exec(str)
==> null
exec 是否有状态并取决于它上一次返回的内容?或者这只是一个错误?我不能让它一直发生。例如,如果上面的“str”是“abc abc”,它就不会发生。
JavaScriptRegExp
对象是有状态的。
当正则表达式是全局的时,如果你在同一个正则表达式对象上调用一个方法,它将从最后一个匹配结束后的索引开始。
当找不到更多匹配项时,索引将0
自动重置为。
要手动重置它,请设置lastIndex
属性。
reg.lastIndex = 0;
这可能是一个非常有用的功能。如果需要,您可以在字符串中的任何点开始评估,或者如果在循环中,您可以在达到所需的匹配数后停止评估。
这是在循环中使用正则表达式的典型方法的演示。它利用了当没有更多匹配项时exec
返回的事实,将null
赋值作为循环条件执行。
var re = /foo_(\d+)/g,
str = "text foo_123 more text foo_456 foo_789 end text",
match,
results = [];
while (match = re.exec(str))
results.push(+match[1]);
演示: http : //jsfiddle.net/pPW8Y/
如果您不喜欢分配的位置,则可以重新设计循环,例如像这样...
var re = /foo_(\d+)/g,
str = "text foo_123 more text foo_456 foo_789 end text",
match,
results = [];
do {
match = re.exec(str);
if (match)
results.push(+match[1]);
} while (match);
演示: http : //jsfiddle.net/pPW8Y/1/
来自MDN 文档:
如果您的正则表达式使用“g”标志,您可以多次使用 exec 方法来查找同一字符串中的连续匹配项。当您这样做时,搜索从由正则表达式的 lastIndex 属性指定的 str 子字符串开始(测试也将推进 lastIndex 属性)。
由于您正在使用该g
标志,所以exec
从最后一个匹配的字符串开始,直到它结束(返回null
),然后重新开始。
就个人而言,我更喜欢反过来 str.match(reg)
如果您的正则表达式需要g
标志(全局匹配),您将需要使用该lastIndex
属性重置索引(最后一个匹配的位置)。
reg.lastIndex = 0;
这是因为每次出现exec()
都会停止,因此您可以在剩余部分再次运行。这种行为也存在于test()
) :
如果您的正则表达式使用“g”标志,您可以多次使用 exec 方法来查找同一字符串中的连续匹配项。当你这样做时,搜索从正则表达式的 lastIndex 属性指定的 str 的子字符串开始(测试也会推进 lastIndex 属性)
当只有一个可能的匹配项时,您可以通过省略g
flag来简单地重写正则表达式,因为索引将自动重置为0
。