PHP正则匹配词首尾含扩展拉丁字符的单词无结果问题排查
问题根源
- 默认单词边界规则不支持非ASCII字符:PHP的PCRE正则引擎默认仅将ASCII范围内的
[a-zA-Z0-9_]判定为单词字符,č、ć、ž、š、đ这类扩展拉丁字符不属于该范围。\b匹配的是「单词字符」和「非单词字符」的交界,当扩展拉丁字符出现在单词首尾时,字符本身会被判定为非单词字符,和前后的空白、标点(同属非单词字符)之间不会触发边界匹配,直接导致匹配失败。 - 正则缺少UTF-8适配修饰符:处理含多字节字符的内容时,正则没有加
u修饰符,多字节字符会被拆分为多个单字节字符处理,进一步加剧匹配异常。
修复方案
仅需要修改preg_match对应的正则规则即可,修改后代码如下:
// 原代码 // if(preg_match("/\b{$value}\b/", $value2)){ // 替换为以下代码 if(preg_match("/(?<!\p{L}){$value}(?!\p{L})/u", $value2)){
说明:
(?<!\p{L})表示当前位置前面没有Unicode字母,(?!\p{L})表示当前位置后面没有Unicode字母,等效于支持全Unicode字符的自定义单词边界- 末尾的
u修饰符会让正则引擎将输入字符串和匹配规则都按UTF-8编码处理,正确识别多字节的扩展拉丁字符
可选优化建议
拆分句子的正则也可以加上u修饰符,避免扩展拉丁字符开头的句子拆分错误:
$sentence = preg_split('/(?<=[.?!])\s+(?=\p{L})/u', $book);
内容的提问来源于stack exchange,提问作者ndrbd
相关产品推荐
相关产品推荐

