为什么Javascript regex.exec()并不总是返回相同的值?

时间:2012-07-13 19:51:45

标签: javascript regex

在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”,则不会发生。

3 个答案:

答案 0 :(得分:175)

JavaScript RegExp对象是有状态的。

当正则表达式是全局的时,如果你在同一个正则表达式对象上调用一个方法,它将从最后一个匹配结束后的索引开始。

如果找不到更多匹配项,索引将自动重置为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]);

DEMO: 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);

DEMO: http://jsfiddle.net/pPW8Y/1/

答案 1 :(得分:15)

来自MDN docs

  

如果正则表达式使用“g”标志,则可以多次使用exec方法在同一个字符串中查找连续匹配。执行此操作时,搜索从正则表达式的lastIndex属性指定的str的子字符串开始(test也将提升lastIndex属性)。

由于您使用g标志,exec从最后一个匹配的字符串继续,直到它到达结尾(返回null),然后重新开始。


就个人而言,我更倾向于使用str.match(reg)

答案 2 :(得分:9)

多个匹配

如果你的正则表达式需要g标志(全局匹配),你需要使用lastIndex属性重置索引(最后一个匹配的位置)。

  

reg.lastIndex = 0;

这是因为exec()stop on each occurence so you can run again on the remaining parttest())也存在此行为:

  

如果正则表达式使用“g”标志,则可以使用exec   方法多次在同一个字符串中查找连续匹配。   执行此操作时,搜索从指定的str的子字符串开始   正则表达式的lastIndex属性(测试也将提前   lastIndex属性)

单场比赛

当只有一个可能的匹配时,您可以通过省略g标志来重写正则表达式,作为index will be automatically reset to 0