PHP获取字符串首字母拼音类

 

getInitialsOfName.php

<?php

/**
 * 获取字符串首字母拼音类
 *      英文字串:不变返回(包括数字)     abc123 => abc123
 *      中文字符串:返回拼音首字符       王小明 => WXM
 *      中英混合串: 返回拼音首字符和英文  我i我j => WIWJ
 * 引入调用
 *  $pinyin = new PYInitials();
 *  $res = $pinyin->getInitials('王王王');
 *  $anchor = substr(ucfirst($res), 0, 1);
 */
class PYInitials
{
    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);
        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;
            }
        }// end for
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值