
本文讲解如何用 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 边界断言),但本例中原始数据结构明确,上述表达式已精准覆盖。
总结:匹配重复结构的核心是用捕获组定义原子单元,再用量词控制重复次数,而非依赖模糊的字符集合。掌握这一点,即可高效解决各类“未知长度但有规律”的文本替换问题。










