批量查找替换:正则、捕获组与命中数预览
把原文粘进去,填查找内容和替换内容;要用正则就勾上「正则」,替换框里用 $1 引用捕获组。先点「只看命中数」确认要改多少处,再点「全部替换」。原文输入框不会被改写,结果只出现在输出框。
什么时候该用批量替换
导出数据里混着全角括号、连续空格、不换行空格(U+00A0),手工改几十处既慢又容易漏。写一条正则一次清干净,是这类工作的标准做法。
格式统一也很常见:把 2024-01-05 批量改成 2024/01/05,或在每个手机号前加国家码,同时用捕获组保住原来的数字。
还有一类是「只改匹配到的部分」。比如一批日志里只想把状态码 500 换成 503,而不动其他数字,正则的边界控制比全文替换安全得多。
- 清理全角/半角混排、连续空格、U+00A0
- 日期、电话、编号的格式统一
- 给匹配到的内容加前缀或后缀,保留原值
- 只替换特定模式,避免误伤其他文本
怎么做才不出错
先点「只看命中数」再替换。命中数能立刻暴露两种错误:写得太宽(把不该改的也算了进去)和写得太窄(根本匹配不到,替换等于没执行)。
捕获组用圆括号分组,替换串里用 $1、$2 引用,$& 代表整个匹配。注意普通(非正则)模式也走同一套替换语法,所以在非正则模式里写 $& 同样会被展开;要替换成一个字面的美元符号,写 $$。
引用不存在的组不会报错:只有一组括号却写 $2,$2 会原样留在结果里。看到结果里冒出 $2,多半是组号数错了。
正则固定用 g 和可选的 i,没有 m、s、u。因此 ^ 和 $ 只匹配整段文本的开头和结尾,. 不跨行,\p{L} 会被当成普通字母 p,\u{1F600} 会被当成字面量。需要 Unicode 属性或码点转义时,改写成代理对(如 \uD83D\uDE00)或直接写具体字符。
正则编译失败时替换不会执行,输出框保留上一次的结果,原文更不会被改动;但错误信息可能只出现在浏览器控制台,页面上看起来像「点了没反应」。遇到这种情况先检查括号是否闭合、方括号是否配对。
贪婪匹配是另一个常见坑:<b>.*</b> 会从第一个 <b> 一直吃到最后一个 </b>,把中间的内容全吞掉;写成 <b>.*?</b> 才逐段匹配。批量替换前,用一小段样本验证结果,比事后回滚便宜得多。
- 先看命中数,确认范围再替换
- 捕获组按左括号顺序编号,别数错
- 替换串里的 $ 要小心,字面美元符号写 $$
- 没有 m/s/u:^ $ 不按行、. 不跨行、\p 和 \u{...} 不可用
替代方案与局限
需要跨行匹配、按行生效的 ^ $,或者 Unicode 属性时,用编辑器的正则替换(VS Code、Sublime)或命令行 perl -0777 -pe、sed。它们支持标志位和更大的文件。
替换规则要条件判断(不同情况换不同内容、需要计算新值)时,写脚本比堆正则可靠:正则越长,越难验证,也越容易在下一次修改时引入新问题。
本工具只把文本当纯文本,不解析 HTML、CSV、JSON 结构,所以改标签属性或某一列仍然可能误伤;几 MB 以上的文本一次性替换会明显卡顿。它适合「看得见的文本清洗」,不适合当数据迁移工具。
- 跨行、多行标志:编辑器或 perl/sed
- 条件替换、需要计算:写脚本
- 结构化数据:先解析再改,不要用正则硬切
常见问题
正则写错会不会把原文改坏?
不会。输入框的内容不会被写回,结果只出现在输出框;正则编译失败时替换根本不会执行,输出框保留上一次的结果。真正的问题是错误信息可能只出现在浏览器控制台,页面上不一定有提示,点了没反应通常就是正则有问题,比如括号没闭合或方括号没配对。
为什么 \p{L} 或 \u{1F600} 匹配不到东西?
正则由 new RegExp 构建,标志只有 g 和可选的 i,没有 u 标志,于是 \p 被当成普通字母 p,\u{1F600} 被当成字面量 u{1F600},不报错但匹配不到。要用 Unicode 属性或码点转义,只能改写成代理对(如 \uD83D\uDE00)或直接写具体字符。
替换框里的 $1、$& 是什么?没有第 2 个括号会怎样?
$1 引用第 1 个捕获组,$& 是整个匹配,$$ 是一个字面的美元符号。引用了不存在的组(比如只有一组括号却写 $2)时,$2 会原样留在结果里。普通(非正则)模式也走同一套替换语法,所以那里的 $& 同样生效。
相关工具:批量查找替换