php获取中文拼音首字母类和函数分享

前端技术 2023/09/02 PHP

一、公司同事整理的类,挺实用的.相信拿出来分享下他不会介意的O(∩_∩)O.不过如果首字母是数字或英文会有些问题.

复制代码 代码如下:

/**
 * Helper_Spell 汉字拼音首字母工具类
 *
 * @category Helper
 * @package  Helper_Spell
 * @author   Lancer <lancer.he@gmail.com>
 * @version  1.0
 * @see      Translation_Big2gb
 */

class Helper_Spell {
/**
 * $_pinyins
 * @var array
 * @access private
 */
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\',
    215249 => \'Z\',
);


/**
 * $_charset
 * @var string
 * @access private
 */
private $_charset = null;

/**
 * __construct 构造函数, 指定需要的编码 default: utf-8 支持utf-8, gb2312
 *
 * @param unknown_type $charset
 */
public function __construct( $charset = \'utf-8\' ) {
    $this->_charset = $charset;
}

/**
 * getInitialsFirst 返回首个汉字的拼音
 *
 * @access public
 * @static
 * @param  string $str
 * @return string
 * @example Helper_Spell::getInitialsFirst(\'我的爱\'); => w
 */
public static function getInitialsFirst( $str, $charset = \'utf-8\' ) {
    $chars = array(
        \'A\',\'B\',\'C\',\'D\',\'E\',\'F\',
        \'G\',\'H\',\'I\',\'J\',\'K\',\'L\',
        \'M\',\'N\',\'O\',\'P\',\'Q\',\'R\',
        \'S\',\'T\',\'U\',\'V\',\'W\',\'X\',
        \'Y\',\'Z\');


    $string = self::getInitials( $str );
    $length = strlen($string);


    for($i=0; $i < $length; $i++) {
        if ( in_array( $string{$i}, $chars ) ) {
            return $string{$i};
        }
    }
    return \'*\';
}


/**
 * getInitials 返回拼音组合
 *
 * @access public
 * @static
 * @param  string $str
 * @return string
 * @example Helper_Spell::getInitials(\'我的爱\'); => wda
 */
public static function getInitials( $str, $charset = \'utf-8\' ) {
    $instance = new Helper_Spell( $charset );
    return $instance->_getInitials( $str );
}


/**
 * _getInitials 获取中文字串的拼音首字符
 *              注:英文的字串:不变返回(包括数字)    eg .abc123 => abc123
 *                  中文字符串:返回拼音首字符        eg. 王小明 => WXM
 *                  中英混合串: 返回拼音首字符和英文  eg. 我i我j => WIWJ
 *
 * @access private
 * @param  string $str
 * @return string
 */
private function _getInitials( $str, $translation=TRUE ){
    if ( empty($str) ) return \'\';
    if ( $this->_isAscii($str[0]) && $this->_isAsciis( $str ))
        return $str;

    if ( $translation )
        $str = Translation_Big2gb::big2gb( $str );

    $result = array();
    if ( $this->_charset == \'utf-8\' ){
        //IGNORE很重要,加上这个就可以是ICONV()函数忽略错误,继续执行
        $str = iconv( \'utf-8\', \'gbk//IGNORE\', $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));
}


/**
 * _msubstr 获取中文字符串
 *
 * @access private
 * @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;
}


/**
 * _cutWord  字符串切分为数组 (汉字或者一个字符为单位)
 *
 * @access private
 * @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;
}


/**
 * _isAscii 判断字符是否是ascii字符
 *
 * @access private
 * @param  string $char
 * @return bool
 */
private function _isAscii( $char ) {
    return ( ord( substr($char,0,1) ) < 160 );
}

 

/**
 * _isAsciis 判断字符串前3个字符是否是ascii字符
 *
 * @access private
 * @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;
}



/**
 * _getChar 通过ASC码返回字母或者数字
 *
 * @access private
 * @param  string $ascii
 * @return string
 */
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 \'~\'; //其他
    }
}


/**
 * _search 查找需要的汉字内码(gb2312) 对应的拼音字符(二分法)
 *
 * @access private
 * @param int $code
 * @return int
 */
private function _search( $code ) {   
    $data = array_keys($this->_pinyins);


    $lower = 0;
    $upper = sizeof($data)-1;


    // 排除非一级汉字
    if ($code < $data[0] || $code > $data[23]) return -1;


    for (;;) {        
        if ( $lower > $upper ){            
            return $data[$lower-1];
        }
        $middle = (int) round(($lower + $upper) / 2);
        if ( !isset($data[$middle]) ) {         
            return -1;
        }


        if ( $data[$middle] < $code ){
            $lower = (int)$middle + 1;
        } else if ( $data[$middle] == $code ) {          
            return $data[$middle];
        } else {
            $upper = (int)$middle - 1;
        }
    }// end for
}

}

本文地址:https://www.stayed.cn/item/4727

转载请注明出处。

本站部分内容来源于网络,如侵犯到您的权益,请 联系我

我的博客

人生若只如初见,何事秋风悲画扇。