正则表达式 /A?/g 不能匹配多个 A

4
为什么正则表达式/A?/g只匹配字符串中的第一个大写字母A?据我所知,如果我执行以下代码:
reg = /A?/g;
match1 = reg.exec('AaAa');
match2 = reg.exec('AaAa');
match3 = reg.exec('AaAa');
console.log(match1, match2, match3); //["A"], [""],[""]

我无法捕获第二个"A"的出现。为什么?虽然?使A变成可选项,但由于它是贪婪的,难道不应该在第二次匹配中选择包括第二个"A"吗?


我不知道,但我总是用另一种方式来做:"AaAa".match(/A?/g) 显示 ["A", "", "A", "", ""] - Kenney
1个回答

4
当您使用exec时,正则表达式对象会“记住”上次匹配的索引。
让我们记录lastIndex的值:
reg = /A?/g;
reg.exec('AaAa');
console.log(reg.lastIndex); // 1
reg.exec('AaAa');
console.log(reg.lastIndex); // 1
reg.exec('AaAa');
console.log(reg.lastIndex); // 1

正如你所看到的,最后匹配的索引没有发生变化!但是为什么呢?

原因是您的正则表达式包含一个可选的匹配项(?)。

第二次调用exec时,它尝试将索引1处的字符"a"A?匹配。这能够成功,因为A?表示字符的可选出现,也就是说在"a"之前匹配了一个空字符串。但是这也意味着输入字符实际上没有被消耗,因此索引没有增加。它是一个零宽度匹配。

同一过程以不同方式可视化:

AaAa // does index 0 match "A?" ? Yes, consume "A" and increase index to 1
^
AaAa // does index 1 match "A?" ? Yes, but do not consume "a"
 ^
AaAa // does index 1 match "A?" ? Yes, but do not consume "a"
 ^
...

调用exec只会匹配第二个"a"

在MDN文档中了解更多关于exec的内容。


如果你将字符可选,它会按照你的预期工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接