正则表达式测试器 打开工具

捕获组与命名组:$1 和 $<name> 怎么对应

捕获组的编号规则只有一句:按左括号出现的顺序,从 1 开始。嵌套时外层先编号,因为它先出现。搞不清编号时,数左括号的位置比数右括号可靠。

编号怎么数

(\d{4})-(\d{2})-(\d{2})

三个组依次是 1、2、3。$1 是年、$2 是月、$3 是日。

嵌套时:

((\d{4})-(\d{2}))

外层 (…) 是第 1 组,里面的 (\d{4}) 是第 2 组,(\d{2}) 是第 3 组。因为外层左括号先出现。

非捕获组为什么有用

(?:…) 只分组不捕获,不占编号。当你想用括号表达「这几个字符作为一个整体重复」,但又不想让编号错位时用它:

(?:ab)+

如果写成 (ab)+,每多一个这样的分组,后面所有 $n 的编号都会往后挪一位——这是「改了一处正则,替换结果全乱」的常见原因。

命名组

(?<year>\d{4}) 定义名为 year 的组,替换时写 $<year>。工具会在结果列表里按名字列出每个命名组捕获的内容。

命名组的好处是抗改动:在它前面插入一个新分组,编号会变,名字不会。所以规则复杂时优先用命名组。

命名组的名字只能是字母、数字、下划线,且不能以数字开头。

「未参与匹配」与「匹配到空」的区别

这两件事看起来一样,实际完全不同:

结果列表把未参与的组显示为空,方便区分。写替换逻辑时这个区别很关键:undefined 该保留原值,"" 该替换成空。

上面这些都不用装软件,也不用注册:打开页面就能用。

打开正则表达式测试器 →

常见问题

最多能有多少个捕获组?

JavaScript 引擎没有硬性上限,但组数多了可读性会崩。超过五六个组建议改用命名组,或拆成多次匹配。

为什么 $1 替换后是空的?

一是组没参与匹配(分支没走到),二是编号数错了。先看结果列表里该组的实际值,再确认编号是否被新加的分组挤位。

命名组和编号组能混用吗?

能。命名组同时也有编号(按左括号顺序),所以 $1 与 $<name> 都能引用同一个组。