You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP字符串匹配函数对相似Unicode字符处理异常的优化求助

Unicode字符匹配异常分析与PHP函数优化

问题背景

现有PHP函数用于匹配数据库单词与用户搜索词,需求是带特殊/Unicode字符的单词能被对应普通字母匹配(如Müller可被Muller/muller/Müller/müller匹配)。函数代码如下:

public function string_contains_word(string $string, string $word): bool {
    // Handling non-ASCII  characters.
    
    $stringconv = iconv('UTF-8', 'ASCII//TRANSLIT', $string);
    $match_og = strpos(mb_strtolower($string), mb_strtolower($word)) !== false;
    $match_conv = strpos(mb_strtolower($stringconv), mb_strtolower($word)) !== false;
    $return_val = ($match_og !== false) ? $match_og : $match_conv;
    return $return_val;
}

但存在异常场景:数据库中存储Yiǧit时,用户搜索Yiğit无结果(不符合预期),搜索Yiǧit则返回结果(符合预期)。视觉上无法区分两个字符串,但strcmp("Yiğit","Yiǧit")返回-3。

字符差异解释

这两个字符串的核心差异在于中间的g字符:

  • Yiğit中的ğ是LATIN SMALL LETTER G WITH BREVE,Unicode编码为U+011F
  • Yiǧit中的ǧ是LATIN SMALL LETTER G WITH CARON,Unicode编码为U+01E7
    二者视觉高度相似,但属于不同的Unicode字符,直接字符串比较或大小写转换后无法匹配。原函数仅对数据库字符串做了ASCII转写,未对用户搜索词做同样处理,导致当搜索词是另一个视觉相似的Unicode字符时,原字符串的转写结果和搜索词的转写结果无法匹配。

代码优化方案

优化思路:将数据库字符串和用户搜索词都统一转换为ASCII转写形式,再进行大小写不敏感的匹配,确保所有视觉相似的Unicode字符都被转成相同的普通字母。同时使用mb_strtolower保证多字节字符的大小写转换正确性。

优化后的代码:

public function string_contains_word(string $string, string $word): bool {
    // 定义统一转写函数,处理Unicode到ASCII的转换
    $transliterate = function(string $str): string {
        // 先按UTF-8编码转换为小写
        $lowerStr = mb_strtolower($str, 'UTF-8');
        // 转写为ASCII,忽略无法转换的字符
        $translit = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $lowerStr);
        // 清理转写后可能残留的特殊符号
        return preg_replace('/[^A-Za-z0-9\s]/', '', $translit);
    };

    // 对数据库字符串和搜索词都做转写处理
    $stringTranslit = $transliterate($string);
    $wordTranslit = $transliterate($word);

    // 同时保留原字符串的匹配(兼容用户输入完全一致的场景)
    $matchOriginal = strpos(mb_strtolower($string, 'UTF-8'), mb_strtolower($word, 'UTF-8')) !== false;
    $matchTranslit = strpos($stringTranslit, $wordTranslit) !== false;

    // 任一匹配成功则返回true
    return $matchOriginal || $matchTranslit;
}

优化点说明

  1. 统一转写逻辑:对输入字符串先做UTF-8编码的大小写转换,再转写为ASCII,最后清理多余符号,确保ğ和ǧ这类视觉相似的字符都被转成g。
  2. 双向转写处理:不再只转写数据库字符串,而是对搜索词也执行相同转写,保证匹配的对称性。
  3. 保留原字符串匹配:兼容用户输入完全一致的场景,提升匹配准确性。
  4. 容错处理:使用iconv的//IGNORE参数,忽略无法转写的字符,避免转换失败。

内容的提问来源于stack exchange,提问作者Amrita Deb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 20:12:41