php获取汉字首字母的函数


Posted in PHP onNovember 07, 2013

网上的方法有不少,都是一样的原理,按照需求,做了一下版本的class类文件,主要功能是:功能明确,易于修改维护和扩展; 英文的字串:不变返回(包括数字);中文字符串:返回拼音首字符; 中英混合串: 返回拼音首字符和英文。该算法采用了二分法查找,修复了之前字母Z读取成Y的错误。好东西要收藏,故在此留下印记,以供后人考证!

<?php 
 /**
* Modified by http://iulog.com @ 2013-05-07
* 修复二分法查找方法
* 汉字拼音首字母工具类
*  注: 英文的字串:不变返回(包括数字)    eg .abc123 => abc123
*      中文字符串:返回拼音首字符        eg. 测试字符串 => CSZFC
*      中英混合串: 返回拼音首字符和英文   eg. 我i我j => WIWJ
*  eg.
*  $py = new str2PY();
*  $result = $py->getInitials('啊吧才的饿飞就好i就看了吗你哦平去人是他uv我想一在');
*/
class str2PY
{
    private $_pinyins = array(
        176161 => 'A',
        176197 => 'B',
        178193 => 'C',
        180238 => 'D',
        182234 => 'E',
        183162 => 'F',
        184193 => 'G',
        185254 => 'H',
        187247 => 'J',
        191166 => 'K',
        192172 => 'L',
        194232 => 'M',
        196195 => 'N',
        197182 => 'O',
        197190 => 'P',
        198218 => 'Q',
        200187 => 'R',
        200246 => 'S',
        203250 => 'T',
        205218 => 'W',
        206244 => 'X',
        209185 => 'Y',
        212209 => 'Z',
    );
    private $_charset = null;
    /**
     * 构造函数, 指定需要的编码 default: utf-8
     * 支持utf-8, gb2312
     *
     * @param unknown_type $charset
     */
    public function __construct( $charset = 'utf-8' )
    {
        $this->_charset    = $charset;
    }
    /**
     * 中文字符串 substr
     *
     * @param string $str
     * @param int    $start
     * @param int    $len
     * @return string
     */
    private function _msubstr ($str, $start, $len)
    {
        $start  = $start * 2;
        $len    = $len * 2;
        $strlen = strlen($str);
        $result = '';
        for ( $i = 0; $i < $strlen; $i++ ) {
            if ( $i >= $start && $i < ($start + $len) ) {
                if ( ord(substr($str, $i, 1)) > 129 ) $result .= substr($str, $i, 2);
                else $result .= substr($str, $i, 1);
            }
            if ( ord(substr($str, $i, 1)) > 129 ) $i++;
        }
        return $result;
    }
    /**
     * 字符串切分为数组 (汉字或者一个字符为单位)
     *
     * @param string $str
     * @return array
     */
    private function _cutWord( $str )
    {
        $words = array();
         while ( $str != "" )
         {
            if ( $this->_isAscii($str) ) {/*非中文*/
                $words[] = $str[0];
                $str = substr( $str, strlen($str[0]) );
            }else{
                $word = $this->_msubstr( $str, 0, 1 );
                $words[] = $word;
                $str = substr( $str, strlen($word) );
            }
         }
         return $words;
    }
    /**
     * 判断字符是否是ascii字符
     *
     * @param string $char
     * @return bool
     */
    private function _isAscii( $char )
    {
        return ( ord( substr($char,0,1) ) < 160 );
    }
    /**
     * 判断字符串前3个字符是否是ascii字符
     *
     * @param string $str
     * @return bool
     */
    private function _isAsciis( $str )
    {
        $len = strlen($str) >= 3 ? 3: 2;
        $chars = array();
        for( $i = 1; $i < $len -1; $i++ ){
            $chars[] = $this->_isAscii( $str[$i] ) ? 'yes':'no';
        }
        $result = array_count_values( $chars );
        if ( empty($result['no']) ){
            return true;
        }
        return false;
    }
    /**
     * 获取中文字串的拼音首字符
     *
     * @param string $str
     * @return string
     */
    public function getInitials( $str )
    {
        if ( empty($str) ) return '';
        if ( $this->_isAscii($str[0]) && $this->_isAsciis( $str )){
            return $str;
        }
        $result = array();
        if ( $this->_charset == 'utf-8' ){
            $str = iconv( 'utf-8', 'gb2312', $str );
        }
        $words = $this->_cutWord( $str );
        foreach ( $words as $word )
        {
            if ( $this->_isAscii($word) ) {/*非中文*/
                $result[] = $word;
                continue;
            }
            $code = ord( substr($word,0,1) ) * 1000 + ord( substr($word,1,1) );
            /*获取拼音首字母A--Z*/
            if ( ($i = $this->_search($code)) != -1 ){
                $result[] = $this->_pinyins[$i];
            }
        }
        return strtoupper(implode('',$result));
    }
    private function _getChar( $ascii )
    {
        if ( $ascii >= 48 && $ascii <= 57){
            return chr($ascii);  /*数字*/
        }elseif ( $ascii>=65 && $ascii<=90 ){
            return chr($ascii);   /* A--Z*/
        }elseif ($ascii>=97 && $ascii<=122){
            return chr($ascii-32); /* a--z*/
        }else{
            return '-'; /*其他*/
        }
    }
    /**
     * 查找需要的汉字内码(gb2312) 对应的拼音字符( 二分法 )
     *
     * @param int $code
     * @return int
     */
    private function _search( $code )
    {
        $data = array_keys($this->_pinyins);
        $lower = 0;
        $upper = sizeof($data)-1;
  $middle = (int) round(($lower + $upper) / 2);
        if ( $code < $data[0] ) return -1;
        for (;;) {
            if ( $lower > $upper ){
                return $data[$lower-1];
            }
            $tmp = (int) round(($lower + $upper) / 2);
            if ( !isset($data[$tmp]) ){
    return $data[$middle];
            }else{ 
    $middle = $tmp;
   }
            if ( $data[$middle] < $code ){
                $lower = (int)$middle + 1;
            }else if ( $data[$middle] == $code ) {
                return $data[$middle];
            }else{
                $upper = (int)$middle - 1;
            }
        }
    }
}
?>
PHP 相关文章推荐
一个从别的网站抓取信息的例子(域名查询)
Oct 09 PHP
在php和MySql中计算时间差的方法
Apr 22 PHP
php日期转时间戳,指定日期转换成时间戳
Jul 17 PHP
php自动加载autoload机制示例分享
Feb 20 PHP
Win2003+apache+PHP+SqlServer2008 配置生产环境
Jul 29 PHP
一个php生成16位随机数的代码(两种方法)
Sep 16 PHP
php微信开发之批量生成带参数的二维码
Jun 26 PHP
浅谈htmlentities 、htmlspecialchars、addslashes的使用方法
Dec 09 PHP
PHP命名空间用法实例分析
Sep 04 PHP
php面试实现反射注入的详细方法
Sep 30 PHP
yii2.0框架多模型操作示例【添加/修改/删除】
Apr 13 PHP
PHP 图片处理
Sep 16 PHP
PHP输出当前进程所有变量/常量/模块/函数/类的示例
Nov 07 #PHP
php cookie使用方法学习笔记分享
Nov 07 #PHP
PHP 5.5 创建和验证哈希最简单的方法详解
Nov 07 #PHP
php使用mb_check_encoding检查字符串在指定的编码里是否有效
Nov 07 #PHP
PHP中spl_autoload_register函数的用法总结
Nov 07 #PHP
php去除HTML标签实例
Nov 06 #PHP
php实现监听事件
Nov 06 #PHP
You might like
为查询结果建立向后/向前按钮
2006/10/09 PHP
Google Voice 短信发送接口PHP开源版(2010.5更新)
2010/07/22 PHP
PHP实现今天是星期几的几种写法
2013/09/26 PHP
PHP文件读写操作相关函数总结
2014/11/18 PHP
PHP符合PSR编程规范的实例分享
2016/12/21 PHP
Google AJAX 搜索 API实现代码
2010/11/17 Javascript
简单的jquery拖拽排序效果实现代码
2011/09/20 Javascript
angular中使用路由和$location切换视图
2015/01/23 Javascript
js控制TR的显示隐藏
2016/03/04 Javascript
AngularJS实现一次监听多个值发生的变化
2016/08/31 Javascript
Chrome不支持showModalDialog模态对话框和无法返回returnValue问题的解决方法
2016/10/30 Javascript
详解js的事件处理函数和动态创建html标记方法
2016/12/16 Javascript
jQuery Validate 相关参数及常用的自定义验证规则
2017/03/06 Javascript
JavaScript闭包_动力节点Java学院整理
2017/06/27 Javascript
浅谈Vue的加载顺序探讨
2017/10/25 Javascript
vue.js学习笔记之v-bind和v-on解析
2018/05/03 Javascript
微信小程序动态生成二维码的实现代码
2018/07/25 Javascript
[37:50]VP vs TNC Supermajor小组赛B组 BO3 第一场 6.2
2018/06/03 DOTA
Python通过90行代码搭建一个音乐搜索工具
2015/07/29 Python
Python 比较两个数组的元素的异同方法
2017/08/17 Python
Django项目中model的数据处理以及页面交互方法
2018/05/30 Python
使用Python创建简单的HTTP服务器的方法步骤
2019/04/26 Python
Python任意字符串转16, 32, 64进制的方法
2019/06/12 Python
Python之Class&amp;Object用法详解
2019/12/25 Python
pycharm 添加解释器的方法步骤
2020/08/31 Python
Python Process创建进程的2种方法详解
2021/01/25 Python
Gloeilampgoedkoop荷兰:在线购买灯泡
2019/02/16 全球购物
幼儿园消防安全制度
2014/01/26 职场文书
迎元旦广播稿
2014/02/22 职场文书
乡镇党建工作汇报材料
2014/08/14 职场文书
2016关于学习党章的心得体会
2016/01/15 职场文书
使用pytorch实现线性回归
2021/04/11 Python
教你怎么用Python selenium操作浏览器对象的基础API
2021/06/23 Python
FP-growth算法发现频繁项集——构建FP树
2021/06/24 Python
Golang数据类型和相互转换
2022/04/12 Golang
利用Apache Common将java对象池化的问题
2022/06/16 Servers