PHP 正则表达式匹配任意字符重复出现两次及以上(含非连续)

PHP 正则表达式匹配任意字符重复出现两次及以上(含非连续)

本文介绍如何使用 php 的 `preg_grep()` 配合正则表达式,精准筛选出**包含至少两个相同字母(无论位置是否相邻)**的字符串,适用于去重校验、模式识别等实际场景。

要实现“匹配任意字母重复出现至少两次(不强制连续)”的需求,关键在于捕获一个字母,并在后续内容中再次匹配该字母。此时应避免使用如 /a{2}/ 这类硬编码字符的写法,而改用反向引用(backreference)配合 Unicode 字母类 /p{L},确保兼容英文字母及多语言文字。

推荐正则表达式:

'/(/p{L}).*/1/'
  • (/p{L}):匹配并捕获任意一个 Unicode 字母(如 a, B, é, 中 等),存入捕获组 1;
  • .*:匹配任意数量(包括零个)的非换行符字符(贪婪匹配);
  • /1:反向引用,要求此处出现与捕获组 1 完全相同的字母。

✅ 示例代码(完整可运行):

$input_lines = ["asdf", "fdas", "asds", "d fm", "dfaa", "aaaa", "aabb", "aaabb"];
$result = preg_grep('/(/p{L}).*/1/', $input_lines);
print_r($result);

输出结果:

松果AI写作

松果AI写作

专业全能的高效AI写作工具

下载

立即学习PHP免费学习笔记(深入)”;

Array
(
    [2] => asds   // s 出现两次(位置 0 和 2)
    [4] => dfaa   // a 出现两次(位置 2 和 3)
    [5] => aaaa   // a 多次重复
    [6] => aabb   // a 两次、b 两次
    [7] => aaabb  // a 至少两次
)

⚠️ 注意事项:

  • 若需仅匹配 ASCII 字母(如排除中文、带音标字符),可将 /p{L} 替换为 [a-zA-Z];
  • .* 默认不跨行,若输入含换行符,请添加 s 修饰符:’/(/p{L}).*/1/s’;
  • 该模式不匹配数字或符号重复(如 “112” 或 “!!”),如需支持,可扩展为 ‘/([/p{L}/p{N}/W]).*/1/’(谨慎使用 /W,它包含空格和标点);
  • 若要求严格两个相同字符且无更多重复(即恰好两次),需改用负向断言,例如 ‘/(/p{L})(?:(?!/1).)*/1(?!(?i)/1)/’,但复杂度显著上升,一般场景无需过度约束。

总结:/(/p{L}).*/1/ 是简洁、高效、国际化友好的解决方案,兼顾可读性与实用性,适用于大多数“检测重复字母”的业务逻辑。

https://www.php.cn/faq/2017437.html

发表回复

Your email address will not be published. Required fields are marked *