正则表达式匹配疑问:为何"ssn"中的"n"被匹配两次?
问题解答
先拆解你的正则结构,明确捕获组的分布:
你的正则 /^(s)(s)?((n)(n)?)?$/ 一共有5个捕获组:
- 组1:
(s)—— 匹配第一个s - 组2:
(s)?—— 可选的第二个s - 组3:
((n)(n)?)—— 包含嵌套组的外层可选组 - 组4:
(n)—— 组3内部的第一个(n)子组 - 组5:
(n)?—— 组3内部的可选(n)子组
当匹配字符串"ssn"时,实际匹配流程是这样的:
- 组1匹配第一个
s,得到值"s" - 组2匹配第二个
s,得到值"s" - 组3开始匹配最后的
"n":- 组4的
(n)会优先匹配这个"n",所以组4的结果是"n" - 组5的
(n)?尝试匹配后续字符,但此时字符串已到结尾,没有剩余内容,所以组5结果为null - 组3作为外层组,它匹配的内容就是内部子组共同匹配的片段——也就是组4捕获的
"n",因此组3的结果也是"n"
- 组4的
这就是你看到同一个"n"被“匹配两次”的原因:嵌套捕获组会分别记录各自匹配的内容,外层组记录整个子表达式的匹配结果,内层组记录自己对应片段的结果,两者指向的是同一个字符片段,但会分别存入匹配结果数组中。
如果想让组3匹配"n"时,组4和组5都返回null,你需要调整正则结构,把内部的子组改成非捕获组(用(?:...)语法)。比如将正则修改为 /^(s)(s)?((?:n)(?:n)?)?$/,此时匹配"ssn"的结果会变成:
[ "ssn", "s", "s", "n", null ]
(因为去掉了两个内层捕获组,结果数组的长度会缩短,仅保留外层组的捕获结果)
内容的提问来源于stack exchange,提问作者user1655229
相关产品推荐
相关产品推荐

