当前位置: 首页 > 面试题库 >

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

华俊弼
2023-03-14
问题内容

我currentyl不知道如何对包含PHP中UTF-8编码字符串的数组进行排序。该数组来自LDAP服务器,因此通过数据库排序(不会有问题)不是解决方案。以下内容不适用于我的Windows开发计算机(尽管我认为这至少应该是一个可能的解决方案):

$array=array('Birnen', 'Äpfel', 'Ungetüme', 'Apfel', 'Ungetiere', 'Österreich');
$oldLocal=setlocale(LC_COLLATE, "0");
var_dump(setlocale(LC_COLLATE, 'German_Germany.65001'));
usort($array, 'strcoll');
var_dump(setlocale(LC_COLLATE, $oldLocal));
var_dump($array);

输出为:

string(20) "German_Germany.65001"
string(1) "C"
array(6) {
  [0]=>
  string(6) "Birnen"
  [1]=>
  string(9) "Ungetiere"
  [2]=>
  string(6) "Äpfel"
  [3]=>
  string(5) "Apfel"
  [4]=>
  string(9) "Ungetüme"
  [5]=>
  string(11) "Österreich"
}

这是完全废话。使用1252作为的代码页setlocale()会提供另一种输出,但仍然是一个明显错误的输出:

string(19) "German_Germany.1252"
string(1) "C"
array(6) {
  [0]=>
  string(11) "Österreich"
  [1]=>
  string(6) "Äpfel"
  [2]=>
  string(5) "Apfel"
  [3]=>
  string(6) "Birnen"
  [4]=>
  string(9) "Ungetüme"
  [5]=>
  string(9) "Ungetiere"
}

有没有一种方法可以对具有UTF-8字符串语言环境的数组进行排序?

刚刚指出,这似乎是Windows上的PHP问题,因为与de_DE.utf8语言环境相同的代码段在Linux机器上也可以使用。不过,针对此Windows特定问题的解决方案将是不错的…


问题答案:

最终,由于Huppie发现了明显的PHP错误,因此如果不使用ΤζΩΤΙΙΙΟΥ所建议的不使用重新编码的字符串(UTF-8→Windows-1252或ISO-8859-1),就无法以简单的方式解决此问题。总结问题,我创建了以下代码段,清楚地说明了问题是使用65001
Windows-UTF-8代码页时的strcoll()函数。

function traceStrColl($a, $b) {
    $outValue=strcoll($a, $b);
    echo "$a $b $outValue\r\n";
    return $outValue;
}

$locale=(defined('PHP_OS') && stristr(PHP_OS, 'win')) ? 'German_Germany.65001' : 'de_DE.utf8';

$string="ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜabcdefghijklmnopqrstuvwxyzäöüß";
$array=array();
for ($i=0; $i<mb_strlen($string, 'UTF-8'); $i++) {
    $array[]=mb_substr($string, $i, 1, 'UTF-8');
}
$oldLocale=setlocale(LC_COLLATE, "0");
var_dump(setlocale(LC_COLLATE, $locale));
usort($array, 'traceStrColl');
setlocale(LC_COLLATE, $oldLocale);
var_dump($array);

结果是:

string(20) "German_Germany.65001"
a B 2147483647
[...]
array(59) {
  [0]=>
  string(1) "c"
  [1]=>
  string(1) "B"
  [2]=>
  string(1) "s"
  [3]=>
  string(1) "C"
  [4]=>
  string(1) "k"
  [5]=>
  string(1) "D"
  [6]=>
  string(2) "ä"
  [7]=>
  string(1) "E"
  [8]=>
  string(1) "g"
  [...]

相同代码段可在Linux机器上运行,而不会产生以下输出问题:

string(10) "de_DE.utf8"
a B -1
[...]
array(59) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "A"
  [2]=>
  string(2) "ä"
  [3]=>
  string(2) "Ä"
  [4]=>
  string(1) "b"
  [5]=>
  string(1) "B"
  [6]=>
  string(1) "c"
  [7]=>
  string(1) "C"
  [...]

当使用Windows-1252(ISO-8859-1)编码的字符串(当然mb_ *编码和语言环境必须更改)时,该代码段也可以使用。

我在bugs.php.net上提交了错误报告:错误#46165
strcoll()在Windows上不适用于UTF-8字符串
。如果您遇到相同的问题,则可以在错误报告页面上向PHP团队提供反馈(另外两个可能相关的错误被归类为
伪造 -我认为此错误不是 伪造的 ;-)。

感谢大家。



 类似资料:
  • 问题内容: 我有一个包含多个数组的数组,我想根据这些数组中的某个字符串对数组进行排序。 如何按名称排序,以便 阿尔伯特排 在首位, 齐默尔曼排 在最后? 我知道如果可以使用整数进行排序,但是字符串使我毫无头绪,该怎么办。 谢谢您帮忙!:) 问题答案: 这可以通过将支持函数作为参数传递给方法调用来实现。 像这样:

  • 本文向大家介绍Swift对字符串数组进行排序,包括了Swift对字符串数组进行排序的使用技巧和注意事项,需要的朋友参考一下 例子 3.0 最简单的方法是使用sorted(): 或者 sort() 您可以将闭包作为排序参数: 尾随闭包的替代语法: 但是,如果数组中的元素不一致,则会出现意外结果: 要解决此问题,请对元素的小写版本进行排序: 或者import Foundation使用NSString的

  • 问题内容: 我在排序包含整数的字符串时遇到问题。如果使用下面的代码,我将进行排序:1some,2some,20some,21some,3some,一些 但是我希望将其排序为:1some,2some,3some,20some,21some,一些 我怎样才能做到这一点? 谢谢! 问题答案: 这是有关如何执行此操作的独立示例(未特别优化): 输出量 说明 该示例使用一个常数来推断数字是否位于的起始位置。

  • 问题内容: 允许用户使用字符串数组进行演奏。他们可以将字符串添加到数组中,从数组中删除字符串,在数组中搜索字符串,最终他们将能够对数组进行排序。排序使我很困惑。我尝试了几种不同的方法。第一种方法是将数组转换为ArrayList并使用Collections对ArrayList进行排序,然后将其转换回静态类数组。没用 我尝试的第二种方法是遍历数组,并尝试仅对用户添加的字符串进行排序,而不是对数组中的所

  • 我主要是一个VB.NET程序员,对VTL(Velocity Template Language)非常陌生。我目前正试图定制一个应用程序,使用Velocity模板和Jython。 我在一个现有文件中有以下VTL代码。以下代码从一个JSON文件中获得一些键值对,并将它们以一个简洁的表形式输出到浏览器: 我可以显示$keyset数组: 我试图做的是按字母顺序对$keyset数组中的字符串进行排序。 我尝

  • 问题内容: 我知道这听起来微不足道,但是我没有意识到 的功能很奇怪。我有一个实际上是字符串形式的“数字”列表,因此我先将它们转换为整数,然后尝试进行排序。 给我: 我想要的是 我四处寻找与排序数字集相关的算法,但是我发现所有算法都涉及对字母数字集进行排序。 我知道这可能是个没有脑子的问题,但是google和我的教科书没有提供比该.sort()功能有用的功能。 问题答案: 您实际上尚未将字符串转换为