PHP mb_strpos无法处理希腊字符串


PHP mb_strpos fails for Greek strings

我有一个文件浏览器,我正在尝试查找哪些文件名包含给定的查询。代码如下:

$query = (isset($_POST['s']))? mb_strtolower($_POST['s'],'UTF-8') : ''; 
$res = opendir($dir); 
    while(false!== ($file = readdir($res))) { 
if(mb_strpos(mb_strtolower($file,'UTF-8'),mb_strtolower($query,'UTF-8'),0,'UTF-8')!== false) {
    echo $file;
}}

对于英语单词来说,这很好,但当文本是希腊语时,结果并不像预期的那样,这意味着它适用于一些但不是所有的希腊语单词。有人能帮我解决这个问题吗?

图形元素可能呈现相同或相似,但它们的表示方式不同。例如:

  • ά在这里表示为Unicode字符"希腊小写字母字母ALPHA WITH TONOS"(U+03AC)
  • ά在此处表示为Unicode字符"GREEK SMALL LETTER ALPHA"(U+03B1),后跟Unicode字符"COMBINING ACUTE ACCENT"(U+3001)

这些是直接从您的评论中复制的。


为了比较它们,您应该首先对两个字符串使用normalizer_normalize(),以获得它们的规范化形式。使用哪种类型的规范化表单最终取决于您。有四个:

  1. NFD(正则分解
  2. NFC(标准分解,然后是标准组成
  3. NFKD(兼容性分解
  4. NFKC(相容性分解,然后是正则复合

由于这种规范化完全在内部使用,只需忽略NFC和NFKC,因此无需重新组合。这让您可以选择NFD或NFKD-规范或兼容。这些名字给了你一点线索,让你知道它们在对等方面有多严格。


1.1规范和兼容性等价:

规范等价是表示相同抽象字符的字符或字符序列之间的基本等价,并且在正确显示时应始终具有相同的视觉外观和行为。

兼容性等价是表示相同抽象字符但可能具有不同视觉外观或行为的字符或字符序列之间的较弱等价。


对于搜索,我会选择后者。

示例:

$foo = "παράρτημα";
$bar = "παράρτημα";
var_dump($foo === $bar);
var_dump(
    normalizer_normalize($foo, Normalizer::FORM_KD) ===
    normalizer_normalize($bar, Normalizer::FORM_KD)
);

输出:

bool(false)
bool(true)