这个问题我十多年前学正则的时候就研究过了。是的,当分组带上量词,正则单次匹配完后,分组仍保留的匹配值只有它最后一次匹配到的字符串,在 JavaScript 中可以通过 $1 来获取到:
> "123".replace(/(\d)+/, "$1") > RegExp.$1 '3'
但这并不意味着该分组就真的只匹配了 3,在匹配过程中它是匹配了 3 次的,但那是正则引擎内部的过程,我们拿不到另外两个值。
在 10 多年前还流行一点的 Perl 语言中,它也是大部分现代正则语法的创造者,是可以通过一种高级的正则语法 (?{}) 来内嵌任意代码,从而实现查看正则引擎的匹配过程:
> perl -le '"123456789" =~ /(\d(?{print "分组匹配了:", $1}))+/' 分组匹配了: 分组匹配了:1 分组匹配了:2 分组匹配了:3 分组匹配了:4 分组匹配了:5 分组匹配了:6 分组匹配了:7 分组匹配了:8
这个就是说,当正则引擎每匹配到一次 (\d,就输出一次 $1,注意由于第一次输出时右边的小括号还没闭合,所以输出了空,最后一次输出了 8 而不是 9 也是这个原因,稍微修改一下就对了:
> perl -le '"123456789" =~ /(?:(\d)(?{print "分组匹配了:", $1}))+/' 分组匹配了:1 分组匹配了:2 分组匹配了:3 分组匹配了:4