Javascript:如何在RegEx .exec结果中获得多个匹配项

Tri*_*daz 25 javascript regex v8 node.js

我跑的时候

/(a)/g.exec('a a a ').length
Run Code Online (Sandbox Code Playgroud)

我明白了

2
Run Code Online (Sandbox Code Playgroud)

但我认为它应该回归

3
Run Code Online (Sandbox Code Playgroud)

因为a字符串中有3个,而不是2个!

这是为什么?

我希望能够在RegEx中搜索字符串的所有出现并迭代它们.

FWIW:我正在使用node.js

And*_*ong 37

exec()仅返回第一个匹配的捕获集,而不是您期望的匹配集.所以你真正看到的是$0(整个匹配,"a")和$1(第一次捕获) - 即一个长度为2的数组. exec()同时设计的是你可以再次调用它以获得一场比赛的捕获.来自MDN:

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

  • 顺便说一句,整场比赛是js中的`$ &`. (3认同)

mVC*_*Chr 26

你可以match改用:

'a a a'.match(/(a)/g).length  // outputs: 3
Run Code Online (Sandbox Code Playgroud)

  • 实际上,只要OP不需要每个匹配中的子组,"匹配"就是这种情况的理想工具. (2认同)
  • 只要始终有至少一场比赛。否则,match将返回null而不是一个空数组。 (2认同)

Jea*_*sky 8

你只匹配第一个a.长度为2的原因是它找到第一个匹配和第一个匹配的括号组部分.在你的情况下,他们是相同的.

考虑这个例子.

var a = /b(a)/g.exec('ba ba ba ');
alert(a);
Run Code Online (Sandbox Code Playgroud)

它输出ba, a.数组长度仍为2,但更明显的是发生了什么."ba"是全场比赛. a括号内的第一个分组匹配.

MDN文档支持这一点-只有第一场比赛和含有组返回.要查找所有匹配项,您可以使用mVChr所述的match().


aja*_*ols 6

while循环可以帮助您

x = 'a a a a';
y = new RegExp(/a/g);
while(null != (z=y.exec(x))) {
   console.log(z);     // output: object
   console.log(z[0]);  // ouput: "a"
}
Run Code Online (Sandbox Code Playgroud)

如果添加计数器,则得到它的长度。

x = 'a a a a';
counter = 0;
y = new RegExp(/a/g);
while(null != (z=y.exec(x))) {
   console.log(z);     // output: object
   console.log(z[0]);  // output: "a"
   counter++;
}
console.log(counter);  // output: 4
Run Code Online (Sandbox Code Playgroud)

这是非常安全的,即使没有找到任何匹配项,它也会退出并且counter将为0

主要目的是告诉您如何使用RegExp循环并从相同匹配的RegExp的字符串中获取所有值

  • +1我认为这是最好的解决方案。`.exec` 返回一些 `.match` 未返回的额外属性,它意味着迭代调用以返回每个增量匹配。仅供参考,您可以从 while 循环中删除 `null !=`,因为 null 值将是假值并无论如何都会退出循环。另外,快乐赏金宾果! (3认同)