【问题标题】:Comparing two unicode strings in PHP比较PHP中的两个unicode字符串
【发布时间】:2011-10-14 21:17:55
【问题描述】:

我一直在比较 PHP 中的两个 unicode 字符串,它们都包含特殊的字符 'ö'。一个字符串来自$_GET,另一个是文件系统的文件夹名称(scandir())。两个字符串似乎都和我一样,做一个

var_dump($filter);
var_dump($tail . '/' . $k);

它们也显示了它们的相等性,但具有不同字符串长度(?!):

string '/blöb' (length=7)
string '/blöb' (length=6)

我的 sn-p 比较它们如下所示:

if($filter == ($tail . '/' . $k)) {
    /* ... */
}

这是怎么回事?

附加信息:$tail是一个空字符串:

string '' (length=0)

【问题讨论】:

  • print_r(unpack("H*",$k)) 在您的两种情况下返回什么?
  • 请记住,有些文件系统使用 NFD(或接近它),您可能正在考虑使用 NFC。如果要进行二进制比较,则需要标准化为同一事物。但是对文本进行二进制比较是不明智的。您需要使用 UCA 进行文本比较。上周在 OSCON 看到我的seven-language talk on Unicode

标签: php string unicode utf-8 compare


【解决方案1】:

查看此处:http://en.wikipedia.org/wiki/Unicode_equivalence 并使用此:http://www.php.net/manual/en/class.normalizer.php

你可能在较长的字符串中有一个分解的字符,意思是一个 o,然后是一个覆盖前一个字符的变音符号组合字符。

规范化器功能会解决这样的问题。

作为旁注,如果您将输入用于等价,则应始终规范化输入(例如用户名 - 您要确保两个人不选择相同的用户名,即使字符串的二进制表示发生不同)。

【讨论】:

  • 这个答案需要安装intl。所以如果你有它,那为什么不使用collator_compare?我正在寻找一个不使用intl的答案...
  • @user9645 因此,您想处理具有 大量 复杂性的 unicode 字符串,而无需实际安装知道如何处理 unicode 的库?我不明白这怎么可能。
  • Ariel - 不,我只是想要一个 GNU intl 的替代品。就是这样。
  • @user9645 intl 不是 GNU,它来自 ICU 库(最初由 Talligent 和 IBM 以及 Sun 编写),它是 权威的 unicode 库,实际上是统一码。没有人再使用其他任何东西了。你可以试试iconvuconv 但我不认为可以做到这一点,也不再维护。你能告诉我你为什么要避免国际化吗?
【解决方案2】:

您可以尝试通过 utf8_encode() 解析它们并在那里检查它们吗? PHP 不支持 unicode,因此建议对一些基本的 Unicode 功能使用 utf8_encode/decode。

http://php.net/manual/en/language.types.string.php

【讨论】:

  • 感谢您回答我的问题。我投票给你。
猜你喜欢
  • 2012-03-23
  • 1970-01-01
  • 1970-01-01
  • 2013-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多