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

Javascript: How to get multiple matches in RegEx .exec results

当我跑步

1
/(a)/g.exec('a a a ').length

我懂了

1
2

但我认为它应该回来

1
3

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

这是为什么?

我希望能够在RegEx中搜索字符串的所有出现并对其进行迭代。

FWIW:我正在使用node.js


exec()仅返回第一个匹配项的捕获集,而不返回您期望的匹配项。因此,您真正看到的是$0(整个匹配项" a")和$1(第一个捕获内容),即同时设计了一个长度为2的数组。exec()被设计为可以再次调用它以获取下一个匹配项的捕获。从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).


您可以使用match代替:

1
'a a a'.match(/(a)/g).length  // outputs: 3


您只匹配第一个。长度为2的原因是它正在查找第一个匹配项和第一个匹配项的括号组部分。在您的情况下,它们是相同的。

考虑这个例子。

1
2
var a = /b(a)/g.exec('ba ba ba ');
alert(a);

输出ba, a。数组长度仍为2,但更明显的是发生了什么。" ba"是完整匹配。 a是带括号的第一个分组匹配项。

MDN文档支持此功能-仅返回第一个匹配项和包含的组。要查找所有匹配项,请使用mVChr声明的match()。


while循环可以帮助您

1
2
3
4
5
6
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"
}

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

1
2
3
4
5
6
7
8
9
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

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

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


码:

1
alert('a a a'.match(/(a)/g).length);

输出:

1
3

regexp.exec(str)返回第一个匹配项或整个匹配项以及第一个捕获(当re = /(a)/g;时),如其他答案中所述

1
2
3
4
5
const str = 'a a a a a a a a a a a a a';
const re = /a/g;

const result = re.exec(str);
console.log(result);

但是它也记住在regexp.lastIndex属性中的位置。

下一个呼叫从regexp.lastIndex开始搜索并返回下一个匹配项。

如果没有更多匹配项,则regexp.exec返回null,并且regexp.lastIndex设置为0。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const str = 'a a a';
const re = /a/g;

const a = re.exec(str);
console.log('match : ', a, ' found at : ', re.lastIndex);

const b = re.exec(str);
console.log('match : ', b, ' found at : ', re.lastIndex);

const c = re.exec(str);
console.log('match : ', c, ' found at : ', re.lastIndex);

const d = re.exec(str);
console.log('match : ', d, ' found at : ', re.lastIndex);

const e = re.exec(str);
console.log('match : ', e, ' found at : ', re.lastIndex);

这就是为什么您可以使用while循环,当匹配项为null时将停止的原因

1
2
3
4
5
6
const str = 'a a a';
const re = /a/g;

while(match = re.exec(str)){
  console.log(match, ' found at : ', match.index);
}