sublime跨行匹配需开启dotall模式(.匹配换行符),推荐用[\s\s]?替代.?以避免边界问题;替换时用\1引用捕获组,大文件须锚定范围防卡顿。

Sublime 中跨行匹配必须开启 dotall 模式
默认情况下,. 不匹配换行符,所以写 foo.*bar 是无法跨行匹配的。必须启用单行模式(dotall),让 . 能吃掉换行符。
操作方式很简单:在 Sublime 的查找面板中,点击右下角的 .* 按钮(正则图标)确保它高亮;如果没反应,手动勾选「Dot matches newline」选项(Mac 上是 ⌥+⌘+P,Windows/Linux 是 Alt+Ctrl+P)。
- 不开启时,
start.*end只能匹配同一行内的内容 - 开启后,
start[\s\S]*?end或start.*?end才真正生效(推荐用[\s\S]更稳妥) - 注意:Sublime 的「Dot matches newline」等价于 PCRE 的
/s修饰符,不是/m
用 [\s\S] 替代 .* 避免空匹配和边界问题
.*? 在 dotall 下看似可用,但实际容易因贪婪/懒惰边界模糊导致误删或漏替——尤其当文本里有多个 end 时,start.*?end 可能停在第一个 end 就结束,而非你预期的最后一个。
更可控的方式是显式匹配任意字符(包括换行):[\s\S] 表示“所有空白符 + 所有非空白符”,覆盖全部 Unicode 字符,且无特殊语义干扰。
- 推荐模板:
start[\s\S]*?end(懒惰)或start[\s\S]*end(贪婪) - 若要排除某些中间内容(比如跳过嵌套块),需配合负向先行断言,例如:
start(?:(?!start|end)[\s\S])*end - 注意:Sublime 不支持
(?s)内联修饰符,不能写(?s)start.*?end
替换时保留部分跨行结构,用捕获组加 \1 \2
批量替换不只是删掉一段,经常需要保留开头、修改中间、固定结尾。这时必须用括号分组,并在替换框中用 、 引用。
例如把所有 /* ... */ 多行注释转成 // 单行注释(只取第一行内容):
查找:/\*([\s\S]*?)\*/
替换:// \1
但要注意:如果 [\s\S]*? 匹配到了换行,\1 也会含换行符,导致结果错行。此时可在替换中用 \1 后加 (删掉换行),或改用 [\S\s]*? 并配合 ^/$ 锚点进一步约束。
- 捕获组编号从左到右,按
(出现顺序计,不是按匹配顺序 - 替换框里不能用
$1,只能用\1(Sublime 用反斜杠引用) - 如果正则里用了
(?:...),它不计入编号,适合做逻辑分组但不捕获
大文件慎用 [\s\S]*?会卡死或崩溃
Sublime 的正则引擎对超长跨行匹配效率不高,尤其是 [\s\S]* 这种无锚点、无限制的表达式,在几千行以上的文件里可能假死、未响应,甚至触发 OOM。
真实项目中建议先缩小范围:
- 用
Ctrl+Shift+P→ 「Set Syntax: Plain Text」避免语法高亮干扰匹配 - 先用
^start和end$锚定行首行尾,减少扫描量 - 若目标结构有唯一前缀(如
class Foo {),优先用class\s+\w+\s*\{[\s\S]*?\}而非泛泛的\{[\s\S]*?\} - 实在卡顿,拆成多次小范围替换:先匹配起始行,再用「Find Next」逐个确认
跨行替换不是万能锤,复杂嵌套(如 HTML 里带 JS 的 <script></script> 块)建议交给专用解析器,别硬刚正则。











