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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11477415/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 05:59:29  来源:igfitidea点击:

Why does Javascript's regex.exec() not always return the same value?

javascriptregex

提问by Sam Fen

In the Chrome or Firebug console:

在 Chrome 或 Firebug 控制台中:

reg = /ab/g
str = "abc"
reg.exec(str)
   ==> ["ab"]
reg.exec(str)
   ==> null
reg.exec(str)
   ==> ["ab"]
reg.exec(str)
   ==> null

Is exec somehow stateful and depends on what it returned the previous time? Or is this just a bug? I can't get it to happen all the time. For example, if 'str' above were "abc abc" it doesn't happen.

exec 是否有状态并取决于它上一次返回的内容?或者这只是一个错误?我不能让它一直发生。例如,如果上面的“str”是“abc abc”,它就不会发生。

回答by

A JavaScript RegExpobject is stateful.

JavaScriptRegExp对象是有状态的。

When the regex is global, if you call a method on the same regex object, it will start from the index past the end of the last match.

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

When no more matches are found, the index is reset to 0automatically.

当找不到更多匹配项时,索引将0自动重置为。



To reset it manually, set the lastIndexproperty.

要手动重置它,请设置lastIndex属性。

reg.lastIndex = 0;


This can be a very useful feature. You can start the evaluation at any point in the string if desired, or if in a loop, you can stop it after a desired number of matches.

这可能是一个非常有用的功能。如果需要,您可以在字符串中的任何点开始评估,或者如果在循环中,您可以在达到所需的匹配数后停止评估。



Here's a demonstration of a typical approach to using the regex in a loop. It takes advantage of the fact that execreturns nullwhen there are no more matches by performing the assignment as the loop condition.

这是在循环中使用正则表达式的典型方法的演示。它利用了当没有更多匹配项时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/

演示:http ://jsfiddle.net/pPW8Y/



If you don't like the placement of the assignment, the loop can be reworked, like this for example...

如果您不喜欢分配的位置,则可以重新设计循环,例如这样...

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/

演示:http ://jsfiddle.net/pPW8Y/1/

回答by Niet the Dark Absol

From MDN docs:

来自MDN 文档

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).

如果您的正则表达式使用“g”标志,您可以多次使用 exec 方法来查找同一字符串中的连续匹配项。当您这样做时,搜索从由正则表达式的 lastIndex 属性指定的 str 子字符串开始(测试也将推进 lastIndex 属性)。

Since you are using the gflag, execcontinues from the last matched string until it gets to the end (returns null), then starts over.

由于您正在使用该g标志,所以exec从最后一个匹配的字符串开始,直到它结束(返回null),然后重新开始。



Personally, I prefer to go the other way around with str.match(reg)

就个人而言,我更喜欢反过来 str.match(reg)

回答by édouard Lopez

Multiple Matches

多场比赛

If your regex need the gflag (global match), you will need to reset the index (position of the last match) by using the lastIndexproperty.

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

reg.lastIndex = 0;

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()) :

这是因为每次出现exec()都会停止,因此您可以在剩余部分再次运行。这种行为也存在于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)

如果您的正则表达式使用“g”标志,您可以多次使用 exec 方法来查找同一字符串中的连续匹配项。当你这样做时,搜索从正则表达式的 lastIndex 属性指定的 str 的子字符串开始(测试也会推进 lastIndex 属性)

Single Match

单场比赛

When there is only one possible match, you can simply rewrite you regex by omitting the gflag, as the index will be automatically reset to 0.

当只有一个可能的匹配项时,您可以通过省略gflag来简单地重写正则表达式,因为索引将自动重置为0