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 相关文章推荐
对Session和Cookie的区分与解释
Mar 16 PHP
PHP代码审核的详细介绍
Jun 13 PHP
比较strtr, str_replace和preg_replace三个函数的效率
Jun 26 PHP
PHP函数之日期时间函数date()使用详解
Sep 09 PHP
ThinkPHP的MVC开发机制实例解析
Aug 23 PHP
PHP中iconv函数转码时截断字符问题的解决方法
Jan 21 PHP
php获取网页里所有图片并存入数组的方法
Apr 06 PHP
PHP模拟asp中response类实现方法
Aug 08 PHP
php抛出异常与捕捉特定类型的异常详解
Oct 26 PHP
使用PHPMailer发送邮件实例
Feb 15 PHP
PHP Ajax跨域问题解决方案代码实例
Aug 01 PHP
laravel入门知识点整理
Sep 15 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
Php 构造函数construct的前下划线是双的_
2009/12/08 PHP
php 计划任务 检测用户连接状态
2012/03/29 PHP
php中调用其他系统http接口的方法说明
2014/02/28 PHP
Windows上php5.6操作mongodb数据库示例【配置、连接、获取实例】
2019/02/13 PHP
JavaScript高级程序设计(第3版)学习笔记13 ECMAScript5新特性
2012/10/11 Javascript
hover的用法及live的用法介绍(鼠标悬停效果)
2013/03/29 Javascript
一个很有趣3D球状标签云兼容IE8
2014/08/22 Javascript
详解JavaScript模块化开发
2016/12/04 Javascript
JavaScript实现向select下拉框中添加和删除元素的方法
2017/03/07 Javascript
JavaScript实现滑动导航栏效果
2017/08/30 Javascript
React-Native中禁用Navigator手势返回的示例代码
2017/09/09 Javascript
jQuery判断网页是否已经滚动到浏览器底部的实现方法
2017/10/27 jQuery
JavaScript设计模式之观察者模式实例详解
2019/01/16 Javascript
vue基础之事件v-onclick=&quot;函数&quot;用法示例
2019/03/11 Javascript
Vue 使用Props属性实现父子组件的动态传值详解
2019/11/13 Javascript
Python学习笔记之if语句的使用示例
2017/10/23 Python
解决python3 安装完Pycurl在import pycurl时报错的问题
2018/10/15 Python
Pycharm代码无法复制,无法选中删除,无法编辑的解决方法
2018/10/22 Python
python 实现图片上传接口开发 并生成可以访问的图片url
2019/12/18 Python
PyQt5 界面显示无响应的实现
2020/03/26 Python
Python openpyxl 插入折线图实例
2020/04/17 Python
python算的上脚本语言吗
2020/06/22 Python
简单了解如何封装自己的Python包
2020/07/08 Python
PyTorch中clone()、detach()及相关扩展详解
2020/12/09 Python
python实现银行账户系统
2021/02/22 Python
CSS3 calc()会计算属性详解
2018/02/27 HTML / CSS
CSS3教程:background-clip和background-origin
2008/10/17 HTML / CSS
Electrolux伊莱克斯巴西商店:家用电器、小家电和配件
2018/05/23 全球购物
请写出 float x 与"零值"比较的 if 语句
2016/01/04 面试题
应届护士推荐信
2013/11/16 职场文书
竞争性谈判邀请书
2014/02/06 职场文书
副科级后备干部考察材料
2014/05/15 职场文书
小学课外活动总结
2014/07/09 职场文书
六一文艺汇演主持词
2015/06/30 职场文书
HTML速写之Emmet语法规则的实现
2021/04/07 HTML / CSS
MongoDB误操作后使用oplog恢复数据
2022/04/11 MongoDB