首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >支持Unicode的PHP自然排序算法?

问支持Unicode的PHP自然排序算法?
EN

Stack Overflow用户
提问于 2009-05-07 03:02:26
回答 5查看 12K关注 0票数 20

是否可以使用自然顺序算法对PHP中具有Unicode / UTF-8字符的数组进行排序?例如(此数组中的顺序是正确排序的):

代码语言:javascript
复制
$array = array
(
    0 => 'Agile',
    1 => 'Ágile',
    2 => 'Àgile',
    3 => 'Âgile',
    4 => 'Ägile',
    5 => 'Ãgile',
    6 => 'Test',
);

如果我尝试使用asort($array),就会得到以下结果:

代码语言:javascript
复制
Array
(
    [0] => Agile
    [6] => Test
    [2] => Àgile
    [1] => Ágile
    [3] => Âgile
    [5] => Ãgile
    [4] => Ägile
)

并使用nat排序($array):

代码语言:javascript
复制
Array
(
    [2] => Àgile
    [1] => Ágile
    [3] => Âgile
    [5] => Ãgile
    [4] => Ägile
    [0] => Agile
    [6] => Test
)

如何实现在PHP 5下返回正确结果顺序(0、1、2、3、4、5、6)的函数?所有的多字节字符串函数(mbstring,iconv,.)在我的系统上可用。

编辑:我想输入值,而不是键--我显式定义键(使用asort()而不是sort())的唯一原因是简化查找值的排序哪里出错的工作。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-09-06 10:29:57

搞定了!

代码语言:javascript
复制
$array = array('Ägile', 'Ãgile', 'Test', 'カタカナ', 'かたかな', 'Ágile', 'Àgile', 'Âgile', 'Agile');

function Sortify($string)
{
    return preg_replace('~&([a-z]{1,2})(acute|cedil|circ|grave|lig|orn|ring|slash|tilde|uml);~i', '$1' . chr(255) . '$2', htmlentities($string, ENT_QUOTES, 'UTF-8'));
}

array_multisort(array_map('Sortify', $array), $array);

输出:

代码语言:javascript
复制
Array
(
    [0] => Agile
    [1] => Ágile
    [2] => Âgile
    [3] => Àgile
    [4] => Ãgile
    [5] => Ägile
    [6] => Test
    [7] => かたかな
    [8] => カタカナ
)

更好:

代码语言:javascript
复制
if (extension_loaded('intl') === true)
{
    collator_asort(collator_create('root'), $array);
}

感谢@tchrist!

票数 13
EN

Stack Overflow用户

发布于 2009-05-07 06:55:34

这个问题不像第一眼看上去那么容易回答。这是PHP缺乏unicode支持全力打击您的领域之一。

首先,正如其他海报所建议的那样,所有natsort()与要排序的类型数组的排序无关。您要寻找的是一种区域设置的排序机制,因为使用扩展字符对字符串进行排序始终是使用的语言的问题。让我们以德语为例:a和in有时可以被排序,就好像它们是同一个字母(DIN 5007/1),有时可以像实际上的"AE“(DIN 5007/2)那样排序。相反,在瑞典语中,在字母表的末尾。

如果您不使用Windows,那么幸运的是PHP提供了一些功能。使用setlocale()、usort()、strcoll()和正确的UTF-8语言环境的组合,您可以得到如下内容:

代码语言:javascript
复制
$array = array('Àgile', 'Ágile', 'Âgile', 'Ãgile', 'Ägile', 'Agile', 'Test');
$oldLocal = setlocale(LC_COLLATE, '<<your_RFC1766_language_code>>.utf8');
usort($array, 'strcoll');
setlocale(LC_COLLATE, $oldLocal);

请注意,为了对UTF-8字符串进行排序,必须使用UTF-8语言环境变量。我将上面示例中的区域设置重置为它的原始值,因为使用setlocale()设置区域设置可以在其他运行的PHP中引入副作用--请参阅PHP手册了解更多细节。

当您确实使用机器时,目前没有针对此问题的解决方案,而且在PHP6之前不会有任何解决方案。请看我自己的question,所以针对这个特定的问题。

票数 25
EN

Stack Overflow用户

发布于 2009-05-07 04:32:09

代码语言:javascript
复制
natsort($array);
$array = array_values($array);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/832709

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档