如何在PHP中对UTF-8字符串数组进行排序?

mes*_*cka 18 php arrays sorting utf-8

需要帮助按utf-8排序单词.例如,我们有5个比利时城市.

$array = array('Borgloon','Thuin','Lennik','Éghezée','Aubel');
sort($array); // Expected: Aubel, Borgloon, Éghezée, Lennik, Thuin
              // Actual: Aubel, Borgloon, Lennik, Thuin, Éghezée
Run Code Online (Sandbox Code Playgroud)

城市Éghezée应该是第三名.是否可以使用/设置某种utf-8或创建我自己的角色顺序?

Tha*_*hai 36

intl与PHP 5.3捆绑在一起,它只支持UTF-8.

在这种情况下,您可以使用Collat​​or:

$array = array('Borgloon','Thuin','Lennik','Éghezée','Aubel');
$collator = new Collator('en_US');
$collator->sort($array);
print_r($array);
Run Code Online (Sandbox Code Playgroud)

输出:

Array
(
    [0] => Aubel
    [1] => Borgloon
    [2] => Éghezée
    [3] => Lennik
    [4] => Thuin
)
Run Code Online (Sandbox Code Playgroud)


Fy-*_*Fy- 10

我想你可以使用strcoll:

setlocale(LC_COLLATE, 'nl_BE.utf8');
$array = array('Borgloon','Thuin','Lennik','Éghezée','Aubel');
usort($array, 'strcoll'); 
print_r($array);
Run Code Online (Sandbox Code Playgroud)

结果:

Array
(
    [0] => Aubel
    [1] => Borgloon
    [2] => Éghezée
    [3] => Lennik
    [4] => Thuin
)
Run Code Online (Sandbox Code Playgroud)

您的系统上需要nl_BE.utf8语言环境:

fy@Heisenberg:~$ locale -a | grep nl_BE.utf8
nl_BE.utf8
Run Code Online (Sandbox Code Playgroud)

如果您使用的是debian,则可以使用dpkg --reconfigure locales来添加语言环境.

  • strcoll 无法在使用 utf-8 的 Windows 上运行,因为 CRT 伪造的实现 (2认同)

Jai*_*ick 8

此脚本应以自定义方式解析.我希望它有所帮助.注意mb_strtolower函数.您需要使用它确实使函数大小写不敏感.我没有使用strtolower函数的原因是它不适用于特殊字符.

<?php

function customSort($a, $b) {
    static $charOrder = array('a', 'b', 'c', 'd', 'e', 'é',
                              'f', 'g', 'h', 'i', 'j',
                              'k', 'l', 'm', 'n', 'o',
                              'p', 'q', 'r', 's', 't',
                              'u', 'v', 'w', 'x', 'y', 'z');

    $a = mb_strtolower($a);
    $b = mb_strtolower($b);

    for($i=0;$i<mb_strlen($a) && $i<mb_strlen($b);$i++) {
        $chA = mb_substr($a, $i, 1);
        $chB = mb_substr($b, $i, 1);
        $valA = array_search($chA, $charOrder);
        $valB = array_search($chB, $charOrder);
        if($valA == $valB) continue;
        if($valA > $valB) return 1;
        return -1;
    }

    if(mb_strlen($a) == mb_strlen($b)) return 0;
    if(mb_strlen($a) > mb_strlen($b))  return -1;
    return 1;

}
$array = array('Borgloon','Thuin','Lennik','Éghezée','Aubel');
usort($array, 'customSort');
Run Code Online (Sandbox Code Playgroud)

编辑:抱歉.我在最后一段代码中犯了很多错误.现在进行测试.

编辑{2}:具有多字节功能的所有内容.


小智 7

如果您想使用本机解决方案,那么我可以推荐这个

\n\n
function compare($a, $b)\n{\n        $alphabet = 'a\xc4\x85bc\xc4\x87de\xc4\x99fghijkl\xc5\x82mnno\xc3\xb3qprstuvwxyz\xc5\xba\xc5\xbc'; // i used polish letters\n        $a = mb_strtolower($a);\n        $b = mb_strtolower($b);\n\n        for ($i = 0; $i < mb_strlen($a); $i++) {\n            if (mb_substr($a, $i, 1) == mb_substr($b, $i, 1)) {\n                continue;\n            }\n            if ($i > mb_strlen($b)) {\n                return 1;\n            }\n            if (mb_strpos($alphabet, mb_substr($a, $i, 1)) > mb_strpos($alphabet, mb_substr($b, $i, 1))) {\n                return 1;\n            } else {\n                return -1;\n            }\n        }\n}\n\nusort($needed_array, 'compare');\n
Run Code Online (Sandbox Code Playgroud)\n\n

不确定,这是最好的解决方案,但它对我有用 =)

\n