[英]How can I sort an array of UTF-8 strings in PHP?
need help with sorting words by utf-8.需要帮助按 utf-8 对单词进行排序。 For example, we have 5 cities from Belgium.例如,我们有来自比利时的 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
City Éghezée should be third. City Éghezée应该是第三名。 Is it possible to use/set some kind of utf-8 or create my own character order?是否可以使用/设置某种 utf-8 或创建我自己的字符顺序?
intl comes bundled with PHP from PHP 5.3 and it only supports UTF-8 . intl从 PHP 5.3 开始与 PHP 捆绑在一起,它只支持 UTF-8 。
You can use a Collator in this case:在这种情况下,您可以使用Collator :
$array = array('Borgloon','Thuin','Lennik','Éghezée','Aubel');
$collator = new Collator('en_US');
$collator->sort($array);
print_r($array);
Output:输出:
Array
(
[0] => Aubel
[1] => Borgloon
[2] => Éghezée
[3] => Lennik
[4] => Thuin
)
I think you can use strcoll :我认为你可以使用strcoll :
setlocale(LC_COLLATE, 'nl_BE.utf8');
$array = array('Borgloon','Thuin','Lennik','Éghezée','Aubel');
usort($array, 'strcoll');
print_r($array);
Result:结果:
Array
(
[0] => Aubel
[1] => Borgloon
[2] => Éghezée
[3] => Lennik
[4] => Thuin
)
You need the nl_BE.utf8 locale on your system:您的系统需要 nl_BE.utf8 语言环境:
fy@Heisenberg:~$ locale -a | grep nl_BE.utf8
nl_BE.utf8
If you are using debian you can use dpkg --reconfigure locales to add locales.如果您使用的是 debian,您可以使用dpkg --reconfigure locales添加语言环境。
This script should resolve in a custom way.此脚本应以自定义方式解析。 I hope it help.我希望它有所帮助。 Note the mb_strtolower function.请注意 mb_strtolower 函数。 You need to use it do make the function case insensitive.您需要使用它使函数不区分大小写。 The reason why I didn't use the strtolower function is that it does not work well with special chars.我没有使用 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');
EDIT: Sorry.编辑:对不起。 I made many mistakes in the last code.我在最后的代码中犯了很多错误。 Now is tested.现在正在测试。
EDIT {2}: Everything with multibyte functions.编辑{2}:具有多字节函数的所有内容。
If you want to use native solution, so i can propose this one如果您想使用本机解决方案,那么我可以提出这个
function compare($a, $b)
{
$alphabet = 'aąbcćdeęfghijklłmnnoóqprstuvwxyzźż'; // i used polish letters
$a = mb_strtolower($a);
$b = mb_strtolower($b);
for ($i = 0; $i < mb_strlen($a); $i++) {
if (mb_substr($a, $i, 1) == mb_substr($b, $i, 1)) {
continue;
}
if ($i > mb_strlen($b)) {
return 1;
}
if (mb_strpos($alphabet, mb_substr($a, $i, 1)) > mb_strpos($alphabet, mb_substr($b, $i, 1))) {
return 1;
} else {
return -1;
}
}
}
usort($needed_array, 'compare');
Not sure, that is the best solution, but it works for me =)不确定,这是最好的解决方案,但它对我有用 =)
As for strcoll I guess it was a nice idea, but doesn't seem to work:至于 strcoll 我想这是一个好主意,但似乎不起作用:
<?php
// Some
$strings = array('Alpha', 'Älpha', 'Bravo');
// make it German: A, Ä, B
setlocale(LC_COLLATE, 'de_DE.UTF8', 'de.UTF8', 'de_DE.UTF-8', 'de.UTF-8');
usort($strings, 'strcoll');
var_dump($strings);
// as you can see, Ä is last, so this didn't work
A while back I wrote a UTF-8 to ASCII tool that would convert "älph#bla" to "aelph-bla".不久前,我编写了一个UTF-8 到 ASCII工具,可以将“älph#bla”转换为“aelph-bla”。 You could use this to "normalize" your input to make it sortable.您可以使用它来“规范化”您的输入以使其可排序。 It's basically a replacement similar to what @Nick said.它基本上是类似于@Nick所说的替代品。
You should use a separate array for sorting, as calling urlify() in a usort() callback would be wasting a lot of resources.您应该使用单独的数组进行排序,因为在 usort() 回调中调用 urlify() 会浪费大量资源。 try尝试
<?php
// data to sort
$array = array('Borgloon','Thuin','Lennik','Éghezée','Aubel');
// container for modified strings
$_array = array();
foreach ($array as $k => $v) {
// "normalize" utf8 to ascii
$_array[$k] = urlify($v);
}
// sort the ASCII stuff (while preserving indexes)
asort($_array);
foreach ($_array as $key => &$v) {
// copy the original value of the ASCIIfied element
$v = $array[$k];
}
var_dump($_array);
If you have PHP5.3 or the intl PECL compiled, try @Thai's solution, seems sweet!如果您编译了 PHP5.3 或 intl PECL,请尝试@Thai 的解决方案,看起来不错!
There are great answers here, but this is a dead simple solution for most situations.这里有很好的答案,但对于大多数情况来说,这是一个非常简单的解决方案。
function globalsort($array, $in = 'UTF-8', $out = 'ASCII//TRANSLIT//IGNORE')
{
return usort($array, function ($a, $b) use ($in, $out) {
$a = @iconv($in, $out, $a);
$b = @iconv($in, $out, $b);
return strnatcasecmp($a, $b);
});
}
And use it like so:并像这样使用它:
globalsort($array);
I'd be tempted to loop through the array and convert to English characters before sorting.我很想在排序之前遍历数组并转换为英文字符。 Eg例如
<?php
$array = array('Borgloon','Thuin','Lennik','Éghezée','Aubel');
setlocale(LC_CTYPE, 'nl_BE.utf8');
$newarray = array();
foreach($array as $k => $v) {
$newarray[$k] = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $v);
}
sort($newarray);
print_r($newarray);
?>
Probably not the best in terms of processing speed/resources used.就使用的处理速度/资源而言,可能不是最好的。 But sure does make it easier to understand the code.但肯定会让代码更容易理解。
Edit:编辑:
Thinking about it now, you might be better using some kind of lookup table, something like this:现在考虑一下,您可能最好使用某种查找表,如下所示:
<?php
$accentedCharacters = array ( 'à', 'á', 'â', 'ã', 'ä', 'å', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'ÿ', 'Š', 'Ž', 'š', 'ž', 'Ÿ', 'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý' );
$replacementCharacters = array ( 'a', 'a', 'a', 'a', 'a', 'a', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', 'n', 'o', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', 'y', 'y', 'S', 'Z', 's', 'z', 'Y', 'A', 'A', 'A', 'A', 'A', 'A', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I', 'N', 'O', 'O', 'O', 'O', 'O', 'O', 'U', 'U', 'U', 'U', 'Y' );
$array = array('Borgloon','Thuin','Lennik','Éghezée','Aubel');
$newarray = array();
foreach($array as $k => $v) {
$newarray[$k] = str_replace($accentedCharacters,$replacementCharacters,$v);
}
sort($newarray);
print_r($newarray);
?>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.