PHP基于ICU扩展intl快速实现汉字转拼音及按拼音首字母分组排序的方法


Posted in PHP onMay 03, 2017

本文实例讲述了PHP基于ICU扩展intl快速实现汉字转拼音及按拼音首字母分组排序的方法。分享给大家供大家参考,具体如下:

ICU(International Components for Unicode)里提供了transliterator(直译器),
可以很方便把其他语言(比如简体中文)转为拉丁文表示:
http://cn2.php.net/manual/zh/transliterator.transliterate.php
Transliterator: allows getting latin representation of strings in various languages.

<?php
//文件编码要求是Unicode
header('Content-Type: text/html; charset=utf-8');
echo transliterator_transliterate('Any-Latin', '中华有为');
//输出 zhōng huá yǒu wèi
echo transliterator_transliterate('Any-Latin; Latin-ASCII; Lower()', '中华有为');
//输出 zhong hua you wei
echo transliterator_transliterate('Any-Latin; Latin-ASCII; Upper()', '中华有为');
//输出 ZHONG HUA YOU WEI
echo transliterator_transliterate('Any-Latin', '重阳');
//输出 zhòng yáng (错误,多音字还是坑)

苹果上的CFStringTransform/kCFStringTransformToLatin汉字转拼音也是通过ICU transform实现的:

http://userguide.icu-project.org/transforms/general#TOC-ICU-Transliterators
http://nshipster.com/cfstringtransform/

使用php5-intl(依赖ICU:libicu52)的简体中文(zh_CN)排序器collator按拼音排序:

http://cn2.php.net/manual/zh/collator.sort.php
php-src/ext/intl --enable-intl --with-icu-dir=DIR

相关: MySQL数据表排序规则COLLATE=utf8_general_ci

<?php
header('Content-Type: text/html; charset=utf-8');
$coll = collator_create('zh_CN');
$arr = array('中国','华山','华夏','中华','重阳','重量','b','a',2,1);
collator_sort($coll, $arr);
var_export($arr);
/*输出(可见汉字按照拼音排序,但不能识别多音字"重"):
array (
 0 => 'a',
 1 => 'b',
 2 => '华山',
 3 => '华夏',
 4 => '中国',
 5 => '中华',
 6 => '重量',
 7 => '重阳',
 8 => 1,
 9 => 2,
)
*/

如果元素1和2加上引号变成字符串类型的话,则1和2排序后会出现在开头.

查看已经安装的软件包目录文件结构:

dpkg -L libicu52:amd64
/usr/lib/x86_64-linux-gnu/libicu*
/usr/lib/x86_64-linux-gnu/libicudata.so.52.1 动态库23MB
/usr/lib/x86_64-linux-gnu/libicudata.a       静态库23MB

Windows上则是:

php\icu*.dll
php\ext\php_intl.dll

下面实现了常用的按汉字拼音首字母分组排序的功能:

<?php
header('Content-Type: text/html; charset=utf-8');
$arr = array('百度知道','阿里云','百度百科','阿里巴巴');
$coll = collator_create('zh_CN');
collator_sort($coll, $arr);
var_export($arr);
//输出 array ( 0 => '阿里巴巴', 1 => '阿里云', 2 => '百度百科', 3 => '百度知道', )
$tmp = array();
foreach($arr as $v) {
 $pinyin = transliterator_transliterate('Any-Latin; Latin-ASCII; Upper()', $v);
 $tmp[substr($pinyin, 0, 1)][] = $v;
}
var_export($tmp);
/*输出
array (
 'A' =>
 array (
  0 => '阿里巴巴',
  1 => '阿里云',
 ),
 'B' =>
 array (
  0 => '百度百科',
  1 => '百度知道',
 ),
)
*/

附:

ls命令,Linux和Windows的文件管理器,显示如下:

1  2  a  b  华山  华夏  中国  中华  重量  重阳

数字,字母,汉字(按拼音排序,但不能识别多音字)

汉字方面,下面的自然排序跟上面有所不同:

<?php
header('Content-Type: text/plain; charset=utf-8');
$arr = array('中国','华山','华夏','中华','重阳','重量','b','a',2,1);
natsort($arr); // 等价于 uasort($arr, function($a, $b) { return strnatcmp($a, $b); });
var_export($arr);
/*输出(自然排序下汉字并没有按照拼音进行排序):
array (
 9 => 1,
 8 => 2,
 7 => 'a',
 6 => 'b',
 3 => '中华',
 0 => '中国',
 2 => '华夏',
 1 => '华山',
 5 => '重量',
 4 => '重阳',
)
*/

几种排序的比较:

<?php
header('Content-Type: text/plain; charset=utf-8');
$arr = explode(' ', '1 11 111 112 12 121 122 a aa aaa aab ab aba abb 阿里 百度 中 中国 中国国 中国中 中中 中中国 中中中');
shuffle($arr); //打乱数组
//collator_sort(collator_create('zh_CN'), $arr);
//usort($arr, function($a, $b) { return strnatcmp($a, $b); });
usort($arr, function($a, $b) { return strcmp($a, $b); });
echo implode(' ',$arr);
exit();
?>

ls排序:

1 11 111 112 12 121 122 a aa aaa aab ab aba abb 阿里 百度 中 中国 中国国 中国中 中中 中中国 中中中

collator_sort(zh_CN)排序(类似Windows/Linux桌面文件管理器里的默认按名称上升排列):

1 11 12 111 112 121 122 a aa aaa aab ab aba abb 阿里 百度 中 中国 中国国 中国中 中中 中中国 中中中

strnatcmp排序:

1 11 12 111 112 121 122 a aa aaa aab ab aba abb 中 中中 中中中 中中国 中国 中国中 中国国 百度 阿里

strcmp排序:

1 11 111 112 12 121 122 a aa aaa aab ab aba abb 中 中中 中中中 中中国 中国 中国中 中国国 百度 阿里

PHP 相关文章推荐
帖几个PHP的无限分类实现想法~
Jan 02 PHP
ubuntu10.04配置 nginx+php-fpm模式的详解
Jun 03 PHP
PHP函数extension_loaded()用法实例
Jan 19 PHP
php计算2个日期的差值函数分享
Feb 02 PHP
php自定义错误处理用法实例
Mar 20 PHP
Yii使用migrate命令执行sql语句的方法
Mar 15 PHP
PHP中error_reporting函数用法详细介绍
Jun 11 PHP
Laravel框架实现超简单的分页效果示例
Feb 08 PHP
PHP全局使用Laravel辅助函数dd
Dec 26 PHP
gearman中worker常驻后台,导致MySQL server has gone away的解决方法
Feb 27 PHP
PhpStorm连接服务器并实现自动上传功能
Dec 09 PHP
php swoft框架实例用法
Dec 22 PHP
php中的异常和错误浅析
May 03 #PHP
利用php-cli和任务计划实现刷新token功能的方法
May 03 #PHP
利用php-cli和任务计划实现订单同步功能的方法
May 03 #PHP
php删除数组指定元素实现代码
May 03 #PHP
在php7中MongoDB实现模糊查询的方法详解
May 03 #PHP
PHP里面把16进制的图片数据显示在html的img标签上(实现方法)
May 02 #PHP
php 使用curl模拟ip和来源进行访问的实现方法
May 02 #PHP
You might like
php 仿Comsenz安装效果代码打包提供下载
2010/05/09 PHP
PHP中如何实现常用邮箱的基本判断
2014/01/07 PHP
PHP之密码加密的几种方式
2015/07/29 PHP
PHP实现的微信APP支付功能示例【基于TP5框架】
2019/09/16 PHP
JavaScript中this关键字使用方法详解
2007/03/08 Javascript
Jquery 设置标题的自动翻转
2009/10/03 Javascript
jquery select选中的一个小问题
2009/10/11 Javascript
javascript中万恶的function实例分析
2011/05/25 Javascript
基于jQuery实现模拟页面加载进度条
2013/04/01 Javascript
Jquery中Event对象属性小结
2015/02/27 Javascript
论Bootstrap3和Foundation5网格系统的异同
2016/05/16 Javascript
JS实用技巧小结(屏蔽错误、div滚动条设置、背景图片位置等)
2016/06/16 Javascript
利用jQuery对无序列表排序的简单方法
2016/10/16 Javascript
Jquery uploadify 多余的Get请求(404错误)的解决方法
2017/01/26 Javascript
JavaScript中附件预览功能实现详解(推荐)
2017/08/15 Javascript
Vue项目全局配置微信分享思路详解
2018/05/04 Javascript
24个解决实际问题的ES6代码片段(小结)
2020/02/02 Javascript
vue-cli或vue项目利用HBuilder打包成移动端app操作
2020/07/29 Javascript
vue - props 声明数组和对象操作
2020/07/30 Javascript
Vue中computed及watch区别实例解析
2020/08/01 Javascript
[00:59]DOTA2背景故事第二期之四大基本法则
2020/07/07 DOTA
Python with的用法
2014/08/22 Python
python根据出生年份简单计算生肖的方法
2015/03/27 Python
Ubuntu下使用python读取doc和docx文档的内容方法
2018/05/08 Python
Python中pandas模块DataFrame创建方法示例
2018/06/20 Python
python处理大日志文件
2019/07/23 Python
python实现广度优先搜索过程解析
2019/10/19 Python
python selenium自动化测试框架搭建的方法步骤
2020/06/14 Python
Python 判断时间是否在时间区间内的实例
2020/05/16 Python
Django中的AutoField字段使用
2020/05/18 Python
浅谈pytorch中torch.max和F.softmax函数的维度解释
2020/06/28 Python
春季防火方案
2014/05/10 职场文书
群众路线表态发言材料
2014/10/17 职场文书
婚庆答谢词
2015/01/04 职场文书
法制教育主题班会
2015/08/13 职场文书
Python中time与datetime模块使用方法详解
2022/03/31 Python