
本文讲解如何用 php 的 `preg_replace()` 精准匹配并替换形如 `*-*-*-*` 的不定长交替模式为统一字符串 `***`,重点解析正则逻辑、常见误区及数组批量处理技巧。
在处理结构化文本时,我们常遇到类似 *-*-*-*-* 这样的重复交替模式——它由星号 * 和短横 – 交替组成,且长度不固定。目标是将整个连续出现的该模式(至少包含三组 *- 并以 * 结尾)统一替换为 ***,而非逐个字符替换。
关键在于正确理解模式结构:它并非“任意 * 或 – 的组合”,而是严格遵循 * 开头、*- 重复、最终以 * 收尾的序列。因此,正则表达式必须捕获这一有序重复结构:
$rows = [ 'Blah *-*-*-*-*-*-*-* Blah', 'Blah *-*-*-*-*-*-*-*-* Blah', 'Blah *-*-*-*-*-*-*-*-*-*-*-*-* Blah', ]; $result = preg_replace('/(*-){3,}*/', '***', $rows); // 输出: // [ // 'Blah *** Blah', // 'Blah *** Blah', // 'Blah *** Blah' // ]
✅ 正则解析:
- (*-) —— 捕获组,匹配字面量 *-(注意:* 在字符类外需转义为 *,否则是量词);
- {3,} —— 表示前面的 (*-) 至少连续出现 3 次(即 *-*-*);
- * —— 最后一个独立的 *,补全完整模式(如 *-*-* + * → *-*-*-,但实际输入以 * 结尾,故完整匹配 *-*-*-* 及更长形式)。
⚠️ 常见错误避坑:
- ❌ [*-]{3,}:这是字符类,匹配任意 3 个及以上 * 或 -(如 —、**-、-**),完全不符合交替顺序要求;
- ❌ /[*-]{3,}/:同上,未体现结构约束;
- ❌ 忘记转义 *:在正则中 * 是元字符,必须写成 * 才表示字面星号。
? 进阶提示:
- preg_replace() 支持直接传入数组 $rows,自动对每个元素执行替换并返回新数组,无需 foreach 循环,代码更简洁、性能更优;
- 若需兼容“开头无 *”或“结尾无 *”等变体,可调整正则(如 /(*-*){2,}*/ 或使用 b 边界断言),但本例中原始数据结构明确,上述表达式已精准覆盖。
总结:匹配重复结构的核心是用捕获组定义原子单元,再用量词控制重复次数,而非依赖模糊的字符集合。掌握这一点,即可高效解决各类“未知长度但有规律”的文本替换问题。