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

Posted

技术标签:

【中文标题】为啥 Normalizer::normalize (PHP) 不起作用?【英文标题】:Why Normalizer::normalize (PHP) doesn't work?为什么 Normalizer::normalize (PHP) 不起作用? 【发布时间】:2013-09-02 21:01:38 【问题描述】:

我正在尝试将带有“áéíóú”等字符的字符串标准化为“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áàä, êëéè 

规范化必须做什么?

---已编辑---

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

FORM_D: aáàä, êëéè

在***问题页面中我可以看到(仅在代码示例模式下):

FORM_D: aáàä, êëéè

【问题讨论】:

【参考方案1】:

在this page找到:(链接的文件有不同的措辞,旧的已经不存在了)

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

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

所以消除重音(和类似的)不是Normalizer 的目的。

【讨论】:

【参考方案2】:

NormalizerFORM_D 可以将变音符号从基本字符中分离出来,然后preg_replace 可以消除变音符号:

$string = 'áéíóú';
echo preg_replace('/[\x0300-\x036f]/u', "", Normalizer::normalize($string , Normalizer::FORM_D));
//aeiou

【讨论】:

非常好,我以前用这种方法在 javascript 中做过。它也适用于 PHP。【参考方案3】:

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

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

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

【讨论】:

去除重音最好使用:iconv("UTF-8", "ASCII//TRANSLIT", $text); @StefanoColetta 由于某种原因我无法让它工作。尝试示例字符串jakaś给我jaka?【参考方案4】:

对于一个真正去除重音的函数,到目前为止我发现的最好的是在 wordpress 核心中: https://core.trac.wordpress.org/browser/trunk/src/wp-includes/formatting.php#L1127 remove_accents($string)

(请注意,我已经针对它提交了一个错误,以便他们采用我提供的更新版本,其中记录了每个字符以及它是如何被翻译的。所以它可能会在未来发生变化)

【讨论】:

无论是什么框架,都可以复制粘贴功能。 Wordpress 小心地涵盖了大多数可能的多语言案例,在这种情况下,应将其视为给定问题的有效答案。

以上是关于为啥 Normalizer::normalize (PHP) 不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

在 GWT 中将 éàçè... 替换为等效的“eace”

你应该同步运行方法吗?为啥或者为啥不?

为啥使用 glTranslatef?为啥不直接更改渲染坐标?

为啥 DataGridView 上的 DoubleBuffered 属性默认为 false,为啥它受到保护?

为啥需要softmax函数?为啥不简单归一化?

为啥 g++ 需要 libstdc++.a?为啥不是默认值?