$1被当字面量输出的根本原因是正则模式未激活:需同时满足.\*图标点亮、状态栏显示regex、替换框用$1(非\1或${1});跨行匹配须用[\s\s]*?或启用. matches newline;捕获组编号按左括号顺序,命名组(?p)可用但不改变编号。

为什么$1总被当字面量输出
根本原因不是正则写错了,而是三个条件没同时满足:.*图标没点亮、状态栏没显示Regex、替换框里写了\1或${1}。Sublime 只在正则模式激活时才把(\w+)解析为捕获组;否则它就匹配字面的(\w+)。
务必点击替换面板右下角的.*图标(或按Alt+R),让它变蓝;检查右下角状态栏是否显示Regex;查找内容里真要匹配字面括号(比如func(x)中的()),必须写成func\(x\);替换框里只认$1,不支持\1,${1}部分版本能解析但不稳定。
想输出字面量$1,得写成$$1;写$会报错或被忽略。
跨行匹配时捕获组失效或卡死
.默认不匹配换行符,这是 PCRE 引擎硬限制。哪怕你写了(.*),它也只在单行内匹配——所以/\*.*?\*/跨多行注释根本匹配不到,或者只到第一行末尾就停了。
稳妥做法是放弃.*?,改用显式字符集:[\s\S]*?明确覆盖所有字符(含换行),兼容性更好;匹配大括号体写{[\s\S]*?},别用{.*?};提取函数参数含换行时用([\s\S]*?),比(([^)]*))更安全。
启用. matches newline后若卡死,说明文本含零宽字符或混合编码,先清空白再试;大文件(>5MB)避免直接跨行正则批量替换:先用Find in Files(Ctrl+Shift+F)定位范围,再人工分块操作。
嵌套括号编号和命名组的实际表现
捕获组编号严格按左括号从左到右顺序计数,不管嵌套深度:(a(b(c)))中 = abc、 = bc、 = c;Sublime 不支持(?:)非捕获组,所有(都占编号位。
命名捕获组(?P<name>)</name>可用,替换时用$name或${name},可读性更强;但注意:命名组不改变编号顺序,(?P<outer>a(?P<inner>b))</inner></outer>中$1仍是ab,$2仍是b。
引用超出范围(如只有两组却写$5),Sublime 会原样保留$5字符串;$&表示整个匹配内容,$0不是第一组,它等价于$&。
跨文件替换时$1突然不生效
Ctrl+H里的正则开关和Ctrl+Shift+F(Find in Files)完全独立。很多人以为在替换面板点过.*,全局面板就自动继承——其实不会。打开Ctrl+Shift+F后,必须单独点右下角.*图标(变蓝),再填Where路径(如src/**/*.ts)。
Where别留空或填.,否则可能扫到node_modules或配置文件;多行匹配必须配合(?s)或勾选. matches newline,否则跨文件时每行都算独立上下文,^/$不生效。
替换前务必点Find,看底部面板列出的匹配项是否符合预期;数量异常多时,先缩小Where范围分批操作;替换后不会自动保存,要手动执行File → Save All或Ctrl+K→Ctrl+B。
最常被忽略的是:跨行、跨文件、嵌套编号这三者叠加时,(?s)、(?m)、括号计数必须同步校准,差一个括号或少一个 flag,$1就变成字面量——而且错误不报,只静默失败。











