Regex Pro 的”匹配 / 解释”双面板很多人都会用,但真正吃掉日常 80% 时间的是替换——日志清洗、字段重排、变量重命名、HTML 转义、批量改文件名,每一个都依赖替换模板。这篇把替换面板里所有占位符的语义、跨语言迁移时要改的语法、以及最容易翻车的”链式替换”陷阱一次讲清。
6 种占位符的精确语义
JavaScript(也是 Regex Pro 替换面板)支持的全部占位符,记不全就翻这张表:
| 占位符 | 含义 | 例:(\d{4})-(?<m>\d{2}) 在 2026-05 上 |
|---|---|---|
$& | 整个匹配本身 | $& → 2026-05 |
$1 … $99 | 第 N 个捕获组 | $1/$2 → 2026/05 |
$<name> | 命名捕获组 | $<m>月 → 05月 |
$` | 匹配之前的全部内容 | 整个文本如果是 日期: 2026-05,$` → 日期: |
$' | 匹配之后的全部内容 | 整个文本如果是 2026-05 周一,$' → 周一 |
$$ | 字面 $ 符号 | $$$1 → $2026(一个字面 $ + 第一组) |
注意
$10的解释顺序——引擎优先当成$1后跟字面0,要强制引用第 10 组要写${10}(部分语言支持)或重新排列分组。
6 个高频替换模板
直接抄即可用。Pattern → Replace 都是 Regex Pro 替换面板的写法。
1. 日期重排(ISO → 中文)
Pattern: (?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})
Replace: $<y>年$<m>月$<d>日
2. 蛇形转驼峰
Pattern: _([a-z])
Replace: $1
然后对 $1 加 toUpperCase——但替换模板不支持函数变换,这一步只能切回代码里用回调:str.replace(/_([a-z])/g, (_, c) => c.toUpperCase())。
3. 把所有数字加方括号
Pattern: \d+
Replace: [$&]
4. CSV 字段 quote
Pattern: ([^,\n]*)
Replace: "$1"
注意:含逗号或引号的字段还要先把内部 " 双写转义,单条正则做不到,必须回调。
5. 给所有金额加美元前缀
Pattern: \d+(?:\.\d{2})?
Replace: $$$&
$$ 是字面 $,$& 是匹配——输出 $100.50。
6. 提取 HTML 标签名
Pattern: <(?<tag>[a-z]+\d*)
Replace: $<tag>
跨语言替换语法速查
调好的 pattern + 替换搬到后端要改语法。完整对照:
| 概念 | JavaScript | Python re.sub | Java replaceAll | Go ReplaceAllString |
|---|---|---|---|---|
| 整匹配 | $& | \g<0> | $0 | $0 |
| 数字组 | $1 | \1(推荐 r"\1") | $1 | $1 |
| 命名定义 | (?<n>...) | (?P<n>...) | (?<n>...) | (?P<n>...) |
| 命名引用 | $<n> | \g<n> | ${n}(花括号) | $n 或 ${n} |
字面 $ | $$ | 不需要 | \\\$ 或 Matcher.quoteReplacement() | $$ |
字面 \ | 无 | \\\\(字符串里 \\) | \\\\ | \\ |
Python 跨语言迁移最大坑:JS 写 $<name>,搬到 Python 直接报错——必须改成 \g<name>,而且分组定义也得加 P:(?P<name>...)。Regex Pro 的 ⎘ Py 按钮已经处理这两条。
Java 第二个特殊点:String#replaceAll 第二参在正则替换之外还会再解一遍反斜杠和 $,传任意字符串(比如用户输入)做替换时必须先 Matcher.quoteReplacement(input) 自动转义,否则带 $ 的字符串会抛异常。
三个”看起来对、实际错”的陷阱
1. 链式替换:第二次替换吃掉第一次的输出
经典反例——HTML 实体解码:
// 错:第二步会把第一步产生的 & 当成新的 & 重新解
text.replace(/</g, '<').replace(/&/g, '&')
// 原文:&lt; 期望:< 实际:<
正确做法(一次性回调):
text.replace(/&(amp|lt|gt|quot);/g, (_, g) =>
({ amp: '&', lt: '<', gt: '>', quot: '"' })[g]
)
Regex Pro 替换面板是单次扫描,链式场景必须复制结果再粘回去——或者干脆在工具里调好 pattern + 单次替换、用 ⎘ JS 导出代码后改成回调。
2. .* 贪婪让替换吞掉过多内容
Pattern: <(.*)>
Replace: [$1]
在 <a><b> 上的预期是 [a][b],实际是 [a><b]——.* 贪婪吃到最后一个 >。
修复:用非贪婪 <(.*?)> 或具体字符类 <([^>]*)>,后者还能避免回溯。Regex Pro 的 AST 解释面板会把 .* 标成”任意字符(贪婪,可能引发回溯)“,看到就要警惕。
3. 没匹配到的命名组替换输出空串
Pattern: (?<protocol>https?)?://(?<host>[^/]+)
Replace: [$<protocol>][$<host>]
在 ://example.com 上(缺协议)输出 [][example.com],不是 [$<protocol>][example.com]——$<protocol> 没匹配到时静默输出空串。要给默认值必须切回调:
str.replace(re, (_, protocol = 'https', host) => `[${protocol}][${host}]`)
Regex Pro 在这套工作流里的定位
| 阶段 | Regex Pro 能做 | Regex Pro 不能做 |
|---|---|---|
| 读 pattern | AST 中文解释、量词/分组/断言标层级 | — |
| 写替换 | 6 种占位符实时预览,前 50 条命中 | 函数式回调(要导出代码) |
| 跨语言 | ⎘ JS / Py / Java 复制按钮按方言转换 | Go / Rust / Ruby 需手改 |
| 大文本 | >200KB 自动切 grep 列表模式 | >10MB 浏览器内存吃紧 |
| 性能兜底 | Worker + 2.5s 超时拦灾难性回溯 | 生产环境的 ReDoS 防护需自己加 |
替换是正则的”最后一公里”——pattern 写对了不等于结果对。用 Regex Pro 把模板调到位、再导出到目标语言,能省掉大量在 Node REPL 或 Python shell 里来回粘贴的时间。