仅匹配指定特殊字符的正则表达式命中阿拉伯文字问题求解
问题原因
你的正则会误匹配阿拉伯字母,核心是两个问题:
- 正则没有加
u(Unicode)修饰符:PHP的PCRE正则引擎默认不会按UTF-8规则解析多字节字符,会把阿拉伯语这类非ASCII的多字节字符拆成单个独立字节处理,这些字节的编码值刚好落入你写的特殊字符集合的覆盖范围,因此触发误判。 - 黑名单匹配逻辑本身存在缺陷:你枚举的特殊字符永远无法覆盖所有场景,一旦出现不在你黑名单里的特殊字符就会漏判,且跨语言场景下很容易出现编码解析导致的误判。
最优解决方案
你原本的需求是仅允许「任意语言字母、空格、-、,」,直接用白名单逻辑写正则即可,代码如下:
// 正则说明: // ^ $ 锚定整串匹配,确保所有字符都符合规则 // \p{L} 匹配任意Unicode语言的字母(英文、阿拉伯文、中文等所有语言的字母都支持) // \s 匹配空白字符,仅需要普通空格可替换为空格本身 // , - 是你允许的特殊符号,-放在字符集末尾无需转义 // 末尾u修饰符开启Unicode模式,正确处理多字节字符 $rule = '/^[\p{L}\s,-]+$/u'; $input = "القاهرة - مصر"; if (!preg_match($rule, $input)) { echo '存在非法字符'; } else { echo '字符合法'; }
如果一定要沿用你原来的黑名单校验逻辑,只需要在原来的正则末尾加上u修饰符即可解决阿拉伯语误判问题,但依然存在特殊字符漏判的风险:
// 仅加u修饰符的原有正则 if (preg_match('/[!@#$%^&*<>();{}[\]_؟:\+=~\/\?\.\\\"\'\']+/u', $input)) { echo '匹配到非法字符'; }
内容的提问来源于stack exchange,提问作者user_411
相关产品推荐
相关产品推荐

