教学之友,学习之友。

站长教学网

当前位置: 站长教学网 > 网站编程 > PHP教程 >

PHP汉字转拼音的函数问题解决方法

时间:2012-03-30 10:14来源:未知 作者:ken 点击:

本文和大家分享一下汉字转拼音问题。

以发现很多股票软件都有这问题,比如zgyh 出来的不是中国银行,而是找不到,

这是因为,中国银行的 “行” 查出来读的是 "xing" 。我篇文章我只是提供了一个原始的转换方法,就是查表。

和你以前看过的算法可能不一样的是,我加了一个二分查找,我看到的一个开源的解决方案是顺序查找的。

    关于,多音字问题,我只有一个小规模的多音字表,从所有股票名称里面纠正过来的。解决方案是这样的:在查找拼音的时候,

查找一下这个字是否在多音字表里面,如果是,那么查找前后组成的词,来决定读什么。站长教学网 eduyo.com

<?php
/**
* 初始化
*
* @param string $file 拼音代码对应表
* @return array 把这个对应表映射成array的格式
*/
function pinyin_init($file)
{
   
$pinyin = file($file);
   
if (empty($pinyin)) {
       
throw new Exception("load pinyin table error.");
    }
   
foreach ($pinyin as $k => $item)
    {
       
$item = explode("\t", $item);
       
$item[0] = trim($item[0]);
       
$item[1] = (int)trim($item[1]);
       
$pinyin[$k] = $item;
    }
   
$pinyin[] = array('', -10248); //最后一个拼音的妈是 -10247
    return $pinyin;
}

/**
* 查找一个字符串中,中文字符部分的拼音
*
* @param array $pingyin
* @param string $str       字符串
* @param string $in_encode 字符串的编码
* @return array
*/
function pingyin_get($pingyin, $str, $in_encode = 'gb2312')
{
   
if (strtolower($in_encode) != 'gb2312') {
      
$str = iconv($in_encode, 'gb2312', $str);
      
if (!$str) {
          
throw new Exception('invalid input string.');
       }
    }
   
$pinyin_arr = array();
   
$len = strlen($str);
   
for ($i = 0; $i < $len; $i  )
    {
       
if ($i == $len -1) break;
       
if (($code = pinyin_getcode_($str[$i], $str[$i   1])) != false) {
           
$i  ;
           
if (($py = pinyin_find_($pingyin, $code)) !== false) {
               
$pinyin_arr[substr($str, $i - 1 , 2)] = $py;
            }
        }
    }
   
return $pinyin_arr;
}

/**
* 内部函数,通过拼音码查找汉字
*
* @param array $pingyin
* @param int $code
* @return string/false
*/
function pinyin_find_($pingyin, $code)
{
   
$start = 0;
   
$count = count($pingyin) - 1;
   
$end = $count;
   
if ($code < $pingyin[0][1] || $code >= $pingyin[$end][1]) { //no found.
        return false;
    }
   
while ($start <= $end)
    {
       
$mid = (int)($start   ($end - $start)/2);
       
if ($mid == $count) { //正常情况下,应该是永远都不会执行到这里,但是为了逻辑上清晰点,还是决定写上
            return $pingyin[$mid - 1][0];
        }
else if ($code >= $pingyin[$mid][1] && $code < $pingyin[$mid   1][1]) {
           
return $pingyin[$mid][0];
        }
else if ($code >= $pingyin[$mid   1][1]) {
          
$start = $mid   1;
        }
else {
           
$end = $mid - 1;
        }
    }
   
return false;
}

/**
* 内部函数,通过汉字的第一个字节 和 第二个字节,得到查找的code
*
* @param char $ch1
* @param char $ch2
* @return int
*/
function pinyin_getcode_($ch1, $ch2)
{
   
$num1 = ord($ch1);
   
$num2 = ord($ch2);
   
if ($num1 > 159 && $num1 < 248) {
       
return $num1 * 256   $num2 - 65536;
    }
   
return false;
}

/**
* 基本配置信息
*/
define("CURRENT_PATH", dirname(__FILE__));
$pingin_file = CURRENT_PATH . "/gb-pinyin.table";

$pinyin = pinyin_init($pingin_file);
$py = pingyin_get($pinyin, "中国银行", 'utf-8');
echo iconv('gb2312', 'utf-8', print_r($py, true));
echo implode("'", $py);
?>

(责任编辑:ken)

TAG标签: php 拼音 转换
顶一下
(1)
50%
踩一下
(1)
50%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
注册登录:不允许匿名留言,登录后留言无需输入验证码。
栏目列表
最新内容