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