会用正则做简单匹配之后,下一步就是分组和替换——这才是正则真正强大的地方。这篇文章用例子讲清楚分组、捕获、回溯引用和非捕获组。

分组:把匹配内容拆块

圆括号除了表达“或”,还能把匹配内容分成组,方便后续引用。例如 (\d{4})-(\d{2})-(\d{2}) 匹配日期时,第一组是年份,第二组是月份,第三组是日期。分组让“匹配到了”变成“匹配到了哪几部分”。

回溯引用:替换时保留原内容

回溯引用是在替换时引用前面匹配到的组。比如想把“张三(销售部)”改成“销售部-张三”,用 (\S+)(([^)]+)) 匹配,替换为 $2-$1。本站的正则测试工具支持查看匹配分组,写替换规则前先验证分组是否正确。

命名分组:让规则可读

分组多了以后,$1$2$3 很容易搞混,可以用命名分组:(?<year>\d{4})-(?<month>\d{2}),替换时用 $year/$month。命名分组让正则更接近“看得懂的规则”,长规则尤其推荐。

非捕获组:不占分组编号

只想表达“或”而不想占用分组编号时,用非捕获组 (?:...)。例如 (?:cat|dog)s 匹配 cats 或 dogs,但不会产生多余分组。规则复杂时,非捕获组能避免编号错乱。

贪婪与懒惰匹配

默认匹配是贪婪的,会尽可能多匹配;在量词后加 ? 变成懒惰匹配,尽可能少匹配。例如 "." 匹配双引号内的所有内容(贪婪),".?" 只匹配最短的引号内容。文本清洗时用错贪婪模式,会吞掉不该吞的内容,这是最常见的坑。

实战:整理电话格式

假设要把“010-12345678”统一成“010 1234 5678”,用分组 (\d{3})-(\d{4})(\d{4}) 替换为 $1 $2 $3。先用测试工具输入几组不同格式的样本验证,确认全覆盖再批量应用。正则的进阶用法,都是在“先小样本验证,再全量执行”的流程里练出来的。