为什么Normalizer :: normalize(PHP)不起作用?

时间:2013-08-30 07:51:28

标签: php normalization intl

我正在尝试将带有'áéíóú'等字符的字符串规范化为'aeiou'以简化搜索。

在对this question的回复后,我应该使用Normalizer类来执行此操作。

问题是normalize函数什么都不做。例如,该代码:

<?php echo 'Pérez, NFC: ' . normalizer_normalize('Pérez', Normalizer::NFC) 
    . ' NFD: ' .normalizer_normalize('Pérez', Normalizer::NFD)
    . ' NFKC: ' .normalizer_normalize('Pérez', Normalizer::NFKC) 
    . ' NFKD: ' .normalizer_normalize('Pérez', Normalizer::NFKD)?>
<br/>
<?php echo 'aáàä, êëéè,' 
    . ' FORM_C: ' . normalizer_normalize('aáàä, êëéè', Normalizer::FORM_C )
    . ' FORM_D: ' .normalizer_normalize('aáàä, êëéè', Normalizer::FORM_D)
    . ' FORM_KC: ' .normalizer_normalize('aáàä, êëéè', Normalizer::FORM_KC)
    . ' FORM_KD: ' .normalizer_normalize('aáàä, êëéè', Normalizer::FORM_KD)?>

所示:

Pérez, NFC: Pérez NFD: Pérez NFKC: Pérez NFKD: Pérez
aáàä, êëéè, FORM_C: aáàä, êëéè FORM_D: aáàä, êëéè FORM_KC: aáàä, êëéè FORM_KD: aáàä, êëéè 

应该做什么规范化?

--- --- EDITED

这很奇怪。从Web浏览器复制并粘贴结果时,在编辑器和原始页面中我可以看到:

FORM_D: aáàä, êëéè
在stackoverflow问题页面中我可以看到

(仅在代码示例模式下):

FORM_D: aáàä, êëéè

4 个答案:

答案 0 :(得分:6)

this page上找到:(链接的文档有不同的措辞,旧的不再存在)

  

Unicode和国际化是一个很大的主题,但你应该知道   至少有一件更重要的事情。由于历史原因,Unicode   允许某些字符的替代表示。例如,á   可以用Unicode编写一个预先组合的字符   代码点U + 00E1或作为字母a(U + 0061)的分解序列   加上重音'(U + 0301)。为了比较和   排序,两个这样的表示应该被视为相等。要解决   这个,intl库提供了Normalizer类。这堂课   turn提供了normalize()方法,您可以使用它来转换   字符串到规范化的组合或分解形式。你的申请   应始终将所有字符串转换为一种或另一种形式   在进行比较之前。

echo Normalizer::normalize("a´", Normalizer::FORM_C); // á  
echo Normalizer::normalize("á", Normalizer::FORM_D); // a´

因此,消除重音(和类似)不是Normalizer的目的。

答案 1 :(得分:3)

您要找的是iconv("UTF-8", "ISO-8859-1//TRANSLIT", $text)

http://php.net/manual/function.iconv.php

小心LC_*设置!根据设置,音译可能会发生变化。

答案 2 :(得分:1)

对于实际删除重音的函数,到目前为止我发现的最好的是wordpress核心: https://core.trac.wordpress.org/browser/trunk/src/wp-includes/formatting.php#L1127 remove_accents($字符串)

(注意我已经提交了一个错误,以便他们采用我提供的更新版本,每个角色的文档以及如何进行转换。因此将来可能会发生变化)

答案 3 :(得分:1)

NormalizerFORM_D可以将变音符号与基本字符分开,然后preg_replace可以消除变音符号:

$string = 'áéíóú';
echo preg_replace('/[\x{0300}-\x{036f}]/u', "", Normalizer::normalize($string , Normalizer::FORM_D));
//aeiou