在 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)
If your regex need the g
flag (global match), you will need to reset the index (position of the last match) by using the lastIndex
property.
reg.lastIndex = 0;
This is due to the fact that exec()
will stop on each occurence so you can run again on the remaining part. This behavior also exists with test()
) :
If your regular expression uses the "g" flag, you can use the exec method multiple times to find successive matches in the same string. When you do so, the search starts at the substring of str specified by the regular expression's lastIndex property (test will also advance the lastIndex property)
When there is only one possible match, you can simply rewrite you regex by omitting the g
flag, as the index will be automatically reset to 0
.