【问题标题】:How do I achieve something like MySQL's latin1_general_ci collation in PHP?如何在 PHP 中实现类似 MySQL 的 latin1_general_ci 排序规则?
【发布时间】:2010-11-04 04:43:39
【问题描述】:

我正在编写一个字符串比较函数来对医学术语进行排序,这些术语通常包含来自许多不同欧洲语言的特殊重音字符,我需要以某种方式实现类似于 MySQL 的latin1_general_ci 的排序规则。

首先,我正在对字符串进行一些基本的修改以删除空格、引号、连字符、括号等。当我使用默认语言环境将字符串传递给strcoll() 时,问题就出现了,因为它不聪明足以考虑,例如,带重音的 e 在字典上等同于正常的 e。

我对使用德语或法语等语言环境持谨慎态度,因为它可能不会包含我需要考虑的所有特殊字符。是否有一个语言环境可以给我类似于latin1_general_ci 排序规则的东西?或者是否有其他解决方案?

我的天真的解决方案是创建一个大型关联数组来将重音字母映射到它们的常规字母等价物,然后将其与str_replace() 一起使用,但这听起来很慢而且很乏味(而且容易出错)。如果可能的话,我宁愿使用语言内置的东西。

另外,strcmp()strcasecmp() 是否尊重当前语言环境的排序规则,还是只是 strcoll() 这样做?

【问题讨论】:

    标签: php sorting localization collation strcmp


    【解决方案1】:

    也许是这样的:

    setlocale(LC_COLLATE, 'fr_FR.Latin1', 'fr.Latin1', 'fr_FR.Latin-1', 'fr.Latin-1');
    

    strcmp()strcasecmp() 未本地化。

    【讨论】:

    • 那是法语吗?例如,德语中的字符不会在该排序规则中得到说明吗?还是 FR 在做一些特别的事情?我确实找到了一个“印欧”语言环境,我目前正在测试它是否会产生所需的结果并解释我所追求的特殊字符。
    • 它是法语,但我正在尝试使用 .Latin1 / .Latin-1 修饰符来强制使用该字符集。真正被接受的是神秘的部分。
    • 我刚试过这个,奇怪的是它奏效了。设置默认的“C”以外的语言环境使 strcoll() 能够对所有重音字符进行排序,即使是那些不在该特定语言中的字符。例如,设置 fr_FR 会使 strcoll() 识别德语 ß 字符。奇怪的!感谢您的帮助。
    【解决方案2】:

    您还可以尝试使用iconv 函数来帮助规范化字符串。这将处理带重音的 e 到正常的 e 情况。也请参阅有关 sorting utf8 strings 的相关问题。

    【讨论】:

    • 究竟如何使用iconv?我试过这个: iconv('ISO-8859-1', 'ASCII//TRANSLIT', 'Déjérine-Klumpke') 但它把带重音的 e 字符变成了问号。
    • 我想通了。出于某种原因,要进行音译,您需要设置默认的“C”语言环境以外的语言环境。
    • 请注意,它仍然无法音译不在该语言环境中的字符。例如,我尝试了 en_US,它仍然把上面的重音 e 变成了一个问号。我相信正确的解决方案仍然是设置“C”以外的语言环境,然后使用 strcoll(),因为无论选择的语言环境如何,它似乎都能够整理所有特殊字符。
    • 您是否尝试过将字符串转换为 utf 并将语言环境设置为 utf8?在 python 中,我设法使用docs.python.org/library/unicodedata.html 做你想做的事。我 - 以为 - 我看过一个 php 库来进行规范化/分解,但我现在找不到它。
    猜你喜欢
    • 1970-01-01
    • 2011-11-28
    • 2011-08-18
    • 2011-08-28
    • 2011-11-14
    • 2014-05-20
    • 1970-01-01
    • 2011-06-30
    • 2012-01-19
    相关资源
    最近更新 更多