A-A+

php获取汉字首字母的函数

2020年06月04日 我爱编程 暂无评论

本文介绍用php实现汉字转化为首字母的方法,主要功能是:功能明确,易于修改维护和扩展; 英文的字串:不变返回(包括数字);中文字符串:返回拼音首字符; 中英混合串: 返回拼音首字符和英文

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

  1. <?php
  2.  /**
  3. * Modified by http://iulog.com @ 2013-05-07
  4. * 修复二分法查找方法
  5. * 汉字拼音首字母工具类
  6. *  注: 英文的字串:不变返回(包括数字)    eg .abc123 => abc123
  7. *      中文字符串:返回拼音首字符        eg. 测试字符串 => CSZFC
  8. *      中英混合串: 返回拼音首字符和英文   eg. 我i我j => WIWJ
  9. *  eg.
  10. *  $py = new str2PY();
  11. *  $result = $py->getInitials('啊吧才的饿飞就好i就看了吗你哦平去人是他uv我想一在');
  12. */
  13. class str2PY
  14. {
  15.     private $_pinyins = array(
  16.         176161 => 'A',
  17.         176197 => 'B',
  18.         178193 => 'C',
  19.         180238 => 'D',
  20.         182234 => 'E',
  21.         183162 => 'F',
  22.         184193 => 'G',
  23.         185254 => 'H',
  24.         187247 => 'J',
  25.         191166 => 'K',
  26.         192172 => 'L',
  27.         194232 => 'M',
  28.         196195 => 'N',
  29.         197182 => 'O',
  30.         197190 => 'P',
  31.         198218 => 'Q',
  32.         200187 => 'R',
  33.         200246 => 'S',
  34.         203250 => 'T',
  35.         205218 => 'W',
  36.         206244 => 'X',
  37.         209185 => 'Y',
  38.         212209 => 'Z',
  39.     );
  40.     private $_charset = null;
  41.     /**
  42.      * 构造函数, 指定需要的编码 default: utf-8
  43.      * 支持utf-8, gb2312
  44.      *
  45.      * @param unknown_type $charset
  46.      */
  47.     public function __construct( $charset = 'utf-8' )
  48.     {
  49.         $this->_charset    = $charset;
  50.     }
  51.     /**
  52.      * 中文字符串 substr
  53.      *
  54.      * @param string $str
  55.      * @param int    $start
  56.      * @param int    $len
  57.      * @return string
  58.      */
  59.     private function _msubstr ($str$start$len)
  60.     {
  61.         $start  = $start * 2;
  62.         $len    = $len * 2;
  63.         $strlen = strlen($str);
  64.         $result = '';
  65.         for ( $i = 0; $i < $strlen$i++ ) {
  66.             if ( $i >= $start && $i < ($start + $len) ) {
  67.                 if ( ord(substr($str$i, 1)) > 129 ) $result .= substr($str$i, 2);
  68.                 else $result .= substr($str$i, 1);
  69.             }
  70.             if ( ord(substr($str$i, 1)) > 129 ) $i++;
  71.         }
  72.         return $result;
  73.     }
  74.     /**
  75.      * 字符串切分为数组 (汉字或者一个字符为单位)
  76.      *
  77.      * @param string $str
  78.      * @return array
  79.      */
  80.     private function _cutWord( $str )
  81.     {
  82.         $words = array();
  83.          while ( $str != "" )
  84.          {
  85.             if ( $this->_isAscii($str) ) {/*非中文*/
  86.                 $words[] = $str[0];
  87.                 $str = substr$strstrlen($str[0]) );
  88.             }else{
  89.                 $word = $this->_msubstr( $str, 0, 1 );
  90.                 $words[] = $word;
  91.                 $str = substr$strstrlen($word) );
  92.             }
  93.          }
  94.          return $words;
  95.     }
  96.     /**
  97.      * 判断字符是否是ascii字符
  98.      *
  99.      * @param string $char
  100.      * @return bool
  101.      */
  102.     private function _isAscii( $char )
  103.     {
  104.         return ( ord( substr($char,0,1) ) < 160 );
  105.     }
  106.     /**
  107.      * 判断字符串前3个字符是否是ascii字符
  108.      *
  109.      * @param string $str
  110.      * @return bool
  111.      */
  112.     private function _isAsciis( $str )
  113.     {
  114.         $len = strlen($str) >= 3 ? 3: 2;
  115.         $chars = array();
  116.         for$i = 1; $i < $len -1; $i++ ){
  117.             $chars[] = $this->_isAscii( $str[$i] ) ? 'yes':'no';
  118.         }
  119.         $result = array_count_values$chars );
  120.         if ( emptyempty($result['no']) ){
  121.             return true;
  122.         }
  123.         return false;
  124.     }
  125.     /**
  126.      * 获取中文字串的拼音首字符
  127.      *
  128.      * @param string $str
  129.      * @return string
  130.      */
  131.     public function getInitials( $str )
  132.     {
  133.         if ( emptyempty($str) ) return '';
  134.         if ( $this->_isAscii($str[0]) && $this->_isAsciis( $str )){
  135.             return $str;
  136.         }
  137.         $result = array();
  138.         if ( $this->_charset == 'utf-8' ){
  139.             $str = iconv( 'utf-8''gb2312'$str );
  140.         }
  141.         $words = $this->_cutWord( $str );
  142.         foreach ( $words as $word )
  143.         {
  144.             if ( $this->_isAscii($word) ) {/*非中文*/
  145.                 $result[] = $word;
  146.                 continue;
  147.             }
  148.             $code = ord( substr($word,0,1) ) * 1000 + ord( substr($word,1,1) );
  149.             /*获取拼音首字母A--Z*/
  150.             if ( ($i = $this->_search($code)) != -1 ){
  151.                 $result[] = $this->_pinyins[$i];
  152.             }
  153.         }
  154.         return strtoupper(implode('',$result));
  155.     }
  156.     private function _getChar( $ascii )
  157.     {
  158.         if ( $ascii >= 48 && $ascii <= 57){
  159.             return chr($ascii);  /*数字*/
  160.         }elseif ( $ascii>=65 && $ascii<=90 ){
  161.             return chr($ascii);   /* A--Z*/
  162.         }elseif ($ascii>=97 && $ascii<=122){
  163.             return chr($ascii-32); /* a--z*/
  164.         }else{
  165.             return '-'/*其他*/
  166.         }
  167.     }
  168.     /**
  169.      * 查找需要的汉字内码(gb2312) 对应的拼音字符( 二分法 )
  170.      *
  171.      * @param int $code
  172.      * @return int
  173.      */
  174.     private function _search( $code )
  175.     {
  176.         $data = array_keys($this->_pinyins);
  177.         $lower = 0;
  178.         $upper = sizeof($data)-1;
  179.   $middle = (int) round(($lower + $upper) / 2);
  180.         if ( $code < $data[0] ) return -1;
  181.         for (;;) {
  182.             if ( $lower > $upper ){
  183.                 return $data[$lower-1];
  184.             }
  185.             $tmp = (int) round(($lower + $upper) / 2);
  186.             if ( !isset($data[$tmp]) ){
  187.     return $data[$middle];
  188.             }else{
  189.     $middle = $tmp;
  190.    }
  191.             if ( $data[$middle] < $code ){
  192.                 $lower = (int)$middle + 1;
  193.             }else if ( $data[$middle] == $code ) {
  194.                 return $data[$middle];
  195.             }else{
  196.                 $upper = (int)$middle - 1;
  197.             }
  198.         }
  199.     }
  200. }
  201. ?>

给我留言

Copyright © 四季博客 保留所有权利.   Theme  Ality

用户登录