请选择 进入手机版 | 继续访问电脑版

[PHP编程] PHP中国际化的字符串排序和比较对象详解

[复制链接]
查看141 | 回复33 | 2021-9-13 07:01:10 | 显示全部楼层 |阅读模式
目次

媒介

在 PHP 中,国际化的功能非常丰富,包括很多我们大概 都不知道的东西实在 都非常有效 ,比如说本日 要先容 的这一系列的字符排序和比较的功能。

排序

正常来说,假如 我们对数组中的字符举行 排序,按照的是字符的 ASC2 表的次序 举行 分列 ,假如 是英文还好,但对于中文的话,排序出来的效果 会黑白 常懵逼的。

  1. $arr = ['我','是','硬','核','项', '目', '经', '理'];
  2. sort($arr);
  3. var_dump( $arr );
  4. // array(8) {
  5. // [0]=>
  6. // string(3) "我"
  7. // [1]=>
  8. // string(3) "是"
  9. // [2]=>
  10. // string(3) "核"
  11. // [3]=>
  12. // string(3) "理"
  13. // [4]=>
  14. // string(3) "目"
  15. // [5]=>
  16. // string(3) "硬"
  17. // [6]=>
  18. // string(3) "经"
  19. // [7]=>
  20. // string(3) "项"
  21. // }
复制代码

按照我们的风俗 会以中文的拼音来对汉字举行 排序,这个时间 通常 大家都会选择本身 写排序的算法或者去找合适的 Composer 包。实在 ,PHP 中已经为我们准备 了一个对象就是用来处理这类标题 的。

  1. $coll = new Collator( 'zh_CN' );
  2. $coll->sort($arr);
  3. var_dump( $arr );
  4. // array(8) {
  5. // [0]=>
  6. // string(3) "核"
  7. // [1]=>
  8. // string(3) "经"
  9. // [2]=>
  10. // string(3) "理"
  11. // [3]=>
  12. // string(3) "目"
  13. // [4]=>
  14. // string(3) "是"
  15. // [5]=>
  16. // string(3) "我"
  17. // [6]=>
  18. // string(3) "项"
  19. // [7]=>
  20. // string(3) "硬"
  21. // }
复制代码

没错,正是这个 Collator 类。它在实例化的时间 必要 指定当前的地区 ,比如我们指定为 zh_CN ,也就是中笔墨 符地区 ,这时间 再使用 它的 sort() 方法就可以完成对中笔墨 符的拼音排序。

  1. $coll->sort($arr, Collator::SORT_NUMERIC );
  2. var_dump( $arr );
  3. // array(8) {
  4. // [0]=>
  5. // string(3) "核"
  6. // [1]=>
  7. // string(3) "经"
  8. // [2]=>
  9. // string(3) "理"
  10. // [3]=>
  11. // string(3) "目"
  12. // [4]=>
  13. // string(3) "是"
  14. // [5]=>
  15. // string(3) "我"
  16. // [6]=>
  17. // string(3) "项"
  18. // [7]=>
  19. // string(3) "硬"
  20. // }
  21. $coll->sort($arr, Collator::SORT_STRING );
  22. var_dump( $arr );
  23. // array(8) {
  24. // [0]=>
  25. // string(3) "核"
  26. // [1]=>
  27. // string(3) "经"
  28. // [2]=>
  29. // string(3) "理"
  30. // [3]=>
  31. // string(3) "目"
  32. // [4]=>
  33. // string(3) "是"
  34. // [5]=>
  35. // string(3) "我"
  36. // [6]=>
  37. // string(3) "项"
  38. // [7]=>
  39. // string(3) "硬"
  40. // }
复制代码

Collator 对象的 sort() 方法还支持第二个参数,用于指定当前的排序是按照字符还是数字格式举行 排序。对于纯中文的内容来说,这个没有什么区别。

除了 sort() 方法之外,它还有一个 asort() 方法,就和平凡 的 asort() 函数一样的功能,只不过它也是支持不同的地区 语言的。

  1. $arr = [
  2. 'a' => '100',
  3. 'b' => '7',
  4. 'c' => '50'
  5. ];
  6. $coll->asort($arr, Collator::SORT_NUMERIC );
  7. var_dump( $arr );
  8. // array(3) {
  9. // ["b"]=>
  10. // string(1) "7"
  11. // ["c"]=>
  12. // string(2) "50"
  13. // ["a"]=>
  14. // string(3) "100"
  15. // }
  16. $coll->asort($arr, Collator::SORT_STRING );
  17. var_dump( $arr );
  18. // array(3) {
  19. // ["a"]=>
  20. // string(3) "100"
  21. // ["c"]=>
  22. // string(2) "50"
  23. // ["b"]=>
  24. // string(1) "7"
  25. // }
  26. $arr = [
  27. '中' => '100',
  28. '的' => '7',
  29. '文' => '50'
  30. ];
  31. $coll->asort($arr, Collator::SORT_NUMERIC );
  32. var_dump( $arr );
  33. // array (
  34. // '的' => '7',
  35. // '文' => '50',
  36. // '中' => '100',
  37. // )
  38. $coll->asort($arr, Collator::SORT_STRING );
  39. var_dump( $arr );
  40. // array (
  41. // '中' => '100',
  42. // '文' => '50',
  43. // '的' => '7',
  44. // )
复制代码

asrot() 方法是根据键和值一起举行 排序的,以是 在这里指定 SORT_STRING 和 SORT_NUMERIC 就有显着 的效果 了。我们可以看出,假如 是根据数字排序,那么效果 就是以数字内容为准的,假如 是根据字符排序,那么效果 就是以键值中的字符串部分为基础举行 排序的。

不管是 sort() 还是 asrot() 本质上都和平凡 的 PHP 默认提供的 sort() 和 asrot() 函数一样的。只是它们多了地区 语言的功能而已。

别的 ,Collator 对象中还提供了一个 sortWithSortKeys() 方法,这个是平凡 的 PHP 排序函数中没有的。

  1. $arr = ['我','是','硬','核','项', '目', '经', '理'];
  2. $coll->sortWithSortKeys($arr);
  3. var_dump( $arr );
  4. // array (
  5. // 0 => '核',
  6. // 1 => '经',
  7. // 2 => '理',
  8. // 3 => '目',
  9. // 4 => '是',
  10. // 5 => '我',
  11. // 6 => '项',
  12. // 7 => '硬',
  13. // )
复制代码

它与 sort() 方法是类似 的,但使用 的是 ucol_getSortKey() 来天生 的 ICU 排序键,在大型数组上的速率 更快。

ICU 的全称是 International Components for Unicode ,也就是 Unicode 的国际化组件,它提供了翻译相干 的功能,也就是我们体系 中以及各类编程语言要实现国际化本领 的基础。

比较

接下来就是字符串的比较,比如说我们都知道,"a" 是比 "A" 要大的,由于 在 ASC2 码表中,"A" 是 65 ,"a" 是 97 。当然,这只是默认环境 下的比较,在使用 Collator 对象的函数举行 比较时,则是根据字典库中的排序索引举行 比较的,对于中文来说,基本上就也是按照拼音的次序 来比较了。

  1. var_dump($coll->compare('Hello', 'hello')); // int(1)
  2. var_dump($coll->compare('你好', '您好')); // int(-1)
复制代码

compare() 方法就是用来举行 比较的,假如 两个字符串相称 ,返回的就是 0 ,假如 第一个字符串大于第二个,返回的是 1 ,否则返回的是 -1 。从代码中,我们可以看出 "Hello" 是大于 "hello" 的,"你好" 是小于 "您好" 的( 由于 "您" 多了一个 g )。

属性设置

Collator 对象中还可以设置一些对象的属性。

  1. $coll->setAttribute(Collator::CASE_FIRST, Collator::UPPER_FIRST);
  2. var_dump($coll->getAttribute(Collator::CASE_FIRST)); // int(25)
  3. var_dump($coll->compare('Hello', 'hello')); // int(-1)
  4. $coll->setAttribute(Collator::CASE_FIRST, Collator::LOWER_FIRST);
  5. var_dump($coll->getAttribute(Collator::CASE_FIRST)); // int(24)
  6. var_dump($coll->compare('Hello', 'hello')); // int(1)
  7. $coll->setAttribute(Collator::CASE_FIRST, Collator::OFF);
  8. var_dump($coll->getAttribute(Collator::CASE_FIRST)); // int(16)
  9. var_dump($coll->compare('Hello', 'hello')); // int(1)
复制代码

这里我们是为对象指定 CASE_FIRST 属性,属性值可以指定 大写优先、小写优先 之类的,对于英笔墨 符来说,这个可以影响排序以及对比的效果 。

别的 ,我们还可以通过一个方法获得当前地区 语言的信息。

  1. var_dump($coll->getLocale(Locale::VALID_LOCALE)); // string(10) "zh_Hans_CN"
  2. var_dump($coll->getLocale(Locale::ACTUAL_LOCALE)); // string(2) "zh"
复制代码

这两个参数分别是获得有效 的地区 设置信息和实际 的地区 信息。

排序信息

当然,我们也可以看到详细 的排序信息,也就是字符在 Collator 中的编码。

  1. var_dump(bin2hex($coll->getSortKey('Hello'))); // string(20) "b6b0bebec4010901dc08"
  2. var_dump(bin2hex($coll->getSortKey('hello'))); // string(18) "b6b0bebec401090109"
  3. var_dump(bin2hex($coll->getSortKey('你好'))); // string(16) "7b9b657301060106"
  4. var_dump(bin2hex($coll->getSortKey('您好'))); // string(16) "7c33657301060106"
  5. $coll = collator_create( 'en_US' );
  6. var_dump($coll->compare('Hello', 'hello')); // int(1)
  7. var_dump($coll->compare('你好', '您好')); // int(-1)
  8. var_dump($coll->getLocale(Locale::VALID_LOCALE)); // string(5) "en_US"
  9. var_dump($coll->getLocale(Locale::ACTUAL_LOCALE)); // string(4) "root"
  10. var_dump(bin2hex($coll->getSortKey('Hello'))); // string(20) "3832404046010901dc08"
  11. var_dump(bin2hex($coll->getSortKey('hello'))); // string(18) "383240404601090109"
  12. var_dump(bin2hex($coll->getSortKey('你好'))); // string(20) "fb0b8efb649401060106"
  13. var_dump(bin2hex($coll->getSortKey('您好'))); // string(20) "fba5f8fb649401060106"
复制代码

可以看出,不用同的地区 语言获取到的 getSortKey() 排序键信息是不同的,不过它们都是以 16进制 存储的,这和默认的 ASC2 码完全不同了。

错误信息

  1. $coll = new Collator( 'en_US' );;
  2. $coll->compare( 'y', 'k' );
  3. var_dump($coll->getErrorCode()); // int(0)
  4. var_dump($coll->getErrorMessage()); // string(12) "U_ZERO_ERROR"
复制代码

使用 getErrorCode() 可以获得错误码,使用 getErrorMessage() 可以获得错误信息。关于返回的这个 U_ZERO_ERROR 并没有查找到相干 的资料,盼望 懂行的朋侪 可以回复阐明 ,大家一起学习。

排序规则强度

别的 就是 Collator 对象就还有一个排序强度的设定,不过我测试的效果 并没有表现 出来。

  1. $arr = array( 'a', 'à' ,'A');
  2. $coll = new Collator( 'de_DE' );
  3. $coll->sort($arr);
  4. var_dump($coll->getStrength());
  5. var_dump( $arr ); // int(2)
  6. // array(3) {
  7. // [0]=>
  8. // string(1) "a"
  9. // [1]=>
  10. // string(1) "A"
  11. // [2]=>
  12. // string(2) "à"
  13. // }
  14. $coll->setStrength(Collator::IDENTICAL);
  15. var_dump($coll->getStrength()); // int(15)
  16. $coll->sort($arr);
  17. var_dump( $arr );
  18. $coll->setStrength(Collator::QUATERNARY);
  19. var_dump($coll->getStrength()); // int(3)
  20. $coll->sort($arr);
  21. var_dump( $arr );
  22. $coll->setStrength(Collator::PRIMARY);
  23. var_dump($coll->getStrength()); // int(0)
  24. $coll->sort($arr );
  25. var_dump( $arr );
  26. $coll->setStrength(Collator::TERTIARY);
  27. var_dump($coll->getStrength()); // int(2)
  28. $coll->sort($arr );
  29. var_dump( $arr );
  30. $coll->setStrength(Collator::SECONDARY);
  31. var_dump($coll->getStrength()); // int(1)
  32. $coll->sort($arr );
  33. var_dump( $arr );
复制代码

在官方文档的测试代码的效果 中,指定不同的参数会返回不同的排序次序 ,但我实际 测试的效果 却全都是一样的。以是 这里就不做讲解了,由于 本身 也没搞明白 为什么。大家相识 一下即可,假如 有清晰 这方面知识的朋侪 也请留言回复一起学习哦!

总结

很故意 思的一个对象吧,实在 这个对象也是支持面向过程式的函数写法的,在示例代码中也有使用 面向过程的方式的调用的。总体来说,按拼音排序和比较这两个功能在实际 的开发 中信赖 还是有不少用武之地的,大家可以尝试看看哦!

测试代码:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202011/source/3.PHP中国际化的字符串比较对象.php

参考文档:

https://www.php.net/manual/zh/class.collator.php

到此这篇关于PHP中国际化的字符串排序和比较对象的文章就先容 到这了,更多相干 PHP国际化字符串比较对象内容请搜索 脚本之家从前 的文章或继续欣赏 下面的相干 文章盼望 大家以后多多支持脚本之家!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

avatar 123457242 | 2021-9-13 08:56:30 | 显示全部楼层
怎么我回帖都没人理我呢?
回复

使用道具 举报

avatar wpwexx127388 | 2021-9-15 22:20:13 | 显示全部楼层
太高深了,理解力不够用了!
回复

使用道具 举报

avatar yhzdmb342 | 2021-9-21 06:38:58 | 显示全部楼层
我和我的小伙伴都惊呆了!
回复

使用道具 举报

avatar Runlinh | 2021-9-26 23:01:15 | 显示全部楼层
每次看到admin楼主的帖子都有惊吓!
回复

使用道具 举报

avatar 123457245 | 2021-10-1 22:03:11 | 显示全部楼层
帖子好乱!
回复

使用道具 举报

avatar 123457782 | 2021-10-2 14:20:11 | 显示全部楼层
鸟大了,什么林子都敢进啊!
回复

使用道具 举报

avatar 123456823 | 2021-10-3 05:53:26 | 显示全部楼层
楼上的心情不错啊!
回复

使用道具 举报

楼上的能详细介绍一下么?
回复

使用道具 举报

avatar 沙漠里的鱼2017 | 2021-10-3 08:12:19 | 显示全部楼层
这一年啥事没干,光研究admin楼主的帖子了!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则