我正在尝试使用'áéíóú'等字符对字符串进行规范化,以简化搜索。
在回应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áàä, êëéè
在this page上找到:(链接的文档有不同的措辞,旧的不再存在)
Unicode和国际化是一个很大的主题,但你至少应该知道一件更重要的事情。由于历史原因,Unicode允许某些字符的替代表示。例如,á可以写成一个预编译字符á与Unicode代码点U + 00E1或作为字母a(U + 0061)与重音符号(U + 0301)组合的分解序列。出于比较和排序的目的,两个这样的表示应该被视为相同。为了解决这个问题,intl库提供了Normalizer类。该类又提供了normalize()方法,您可以使用该方法将字符串转换为规范化的组合或分解形式。在执行比较之前,您的应用程序应始终将所有字符串转换为一种或另一种形式。
echo Normalizer::normalize("a´", Normalizer::FORM_C); // á
echo Normalizer::normalize("á", Normalizer::FORM_D); // a´
所以消除口音(和类似的)不是Normalizer
的目的。
你在寻找的是iconv("UTF-8", "ISO-8859-1//TRANSLIT", $text)
。
http://php.net/manual/function.iconv.php
小心LC_*
设置!根据设置,音译可能会发生变化。
Normalizer
与FORM_D
可以将变音符号从基本字符中分离出来,然后preg_replace
可以消除变音符号:
$string = 'áéíóú';
echo preg_replace('/[\x{0300}-\x{036f}]/u', "", Normalizer::normalize($string , Normalizer::FORM_D));
//aeiou
对于实际删除重音的函数,到目前为止我发现的最好的是wordpress核心:https://core.trac.wordpress.org/browser/trunk/src/wp-includes/formatting.php#L1127 remove_accents($ string)
(注意我已经提交了一个错误,以便他们采用我提供的更新版本,每个角色的文档以及如何进行转换。因此将来可能会更改)