我在执行多次相同的正则表达式时看到了一种奇怪的行为:
var r = /(.*)/g
var d = "a"
console.log(r.exec(d))
console.log(r.exec(d))
这会产生:
["a", "a"]
["", ""]
为什么第二次不匹配任何内容?
答案 0 :(得分:7)
这就是g
标志的作用。当你使用它时,exec将从前一个匹配的结尾继续下一个搜索。但是在你的第一场比赛(a
)之后,字符串中没有剩下的东西了,所以你得到一个空的比赛。此空匹配通常用于终止exec
循环。如果您知道只有一个匹配项,请删除g
(表示“全局”搜索)。
请注意,您可以(并且应该)摆脱这些括号。它们只会让您失去性能。如果没有它们,您将只在结果数组中得到一个a
。
如果你想考虑多个匹配,但忽略最后一个空匹配,请使用循环技术:
var match;
while(match = r.exec(d))
// process match[0] here
请注意,如果您实际拥有(有意义的)捕获组,则只需要此循环。如果没有(如果你只想获得完整的匹配),你可以使用match
代替elclanrs指出:
var matches = d.match(r);
修改强>
我刚刚意识到,我所说的大部分内容都是正确的,但不是["", ""]
的实际原因。真正发生的是:第一次.*
匹配a
。第二次引擎尝试在上一次匹配后继续搜索(a
之后)。由于您的模式具有.*
(表示0个或更多字符),因此它现在将继续匹配空字符串(因为它们与模式匹配)。匹配空字符串也不会提升下一次搜索的位置。因此,即使使用.match
,您也会获得["a", ""]
(match
足以聪明地在这种情况下中止)。
事实上,如果你使用循环技术的正则表达式,你将得到一个无限循环(因为match = ["", ""]
显然不会导致循环终止)。但无论如何,你应该意识到由于*
你的模式是荒谬的。它可以匹配任何东西(包括任何东西)。至少使用.+
。无论出于何种目的。
答案 1 :(得分:1)
exec
返回第一个匹配并向前移动内部指针。这样,第二次调用将返回第二次匹配。
由于只有一个匹配,第二个调用返回空结果。