数字RMB转成繁体汉字表示

知识点:

1.%分号只能对int数取余,用%取余存在大数溢出的情况, 32位系统通常最大值是二十亿, 64位系统是大约是9E18,  解决方法:floatVal把整形数字转成浮点型的存储,用fmod函数取余(即使转成浮点型后也不能使用%取余)

2.PHP正则零宽断言(?=exp), 可以正则匹配中加入条件

3.preg_replace替换中文字符,出现乱码情况, 可以在正则后带上/u模式修饰符, 具体描述可在此得到:http://php.net/manual/zh/reference.pcre.pattern.modifiers.php

编程想法:将数字统一转为汉字,当为零时不带上单位, 当不为零时带上单位,

数字每8位进行处理。在transfer转换函数内,每四位进行处理,

最后按照汉字表示法的规则,对得到的字符串替换掉多余的零,以及不符格式的字符。

详细代码如下:

测试数字:1953307170.84

输出结果:拾玖亿伍仟叁佰叁拾萬零柒仟壹佰柒拾圓捌角肆分

$num_to_word = array('零', '壹', '貳', '叁', '肆', '伍', '陸', '柒', '捌', '玖');
$unit = array('分', '角', '圓', '拾', '佰', '仟', '萬', '亿');
$money = 1953307170.84;  //这是测试用的数值
$str = '';

//小数部分单独处理
$money = $money * 100;
$smallNum = $money % 100;
$smallNum = fmod(floatval($money),100);
if ($smallNum !== 0) {
    $jiao = floor($smallNum / 10);
    $fen = $smallNum % 10;
    $str .= $num_to_word[$jiao].$unit[1];  //角
    if ($fen !== 0) { //分
        $str .= $num_to_word[$fen].$unit[0];
    }
}

$money = floor($money / 100);  //去除小数部分
$tmpstr = '';
do {
    if (strlen($tmpstr) > 0) {

        if (strlen($tmpMoney) < 8) {  //如果前一次取余时, 余数不足8位字符串前要加零
            $tmpstr = $num_to_word[0].$tmpstr;
        }
        $tmpstr = $unit[7].$tmpstr; //字符串前添上单位亿
    }
    $tmpMoney = fmod(floatval($money),100000000);
    $money = floor($money / 100000000);
   transfer($tmpMoney,$tmpstr);
} while(fmod(floatval($money),100000000) != 0);

$tmpstr = str_replace(array($unit[3].$num_to_word[0], $num_to_word[1].$unit[3]), $unit[3], $tmpstr);  //去除拾零和壹拾情况
$tmpstr = preg_replace('/'.$num_to_word[0].$num_to_word[0].'+?(?=[壹貳叁肆伍柒捌玖]{1,})/u', $num_to_word[0], $tmpstr);  //当连续两个零以上后面有数字时,用一个零替代, PHP零宽断言
$tmpstr = preg_replace('/'.$num_to_word[0].$num_to_word[0].'+?/u', '', $tmpstr); //当连续两个零以上后面无数字时,用空替代
if (Strlen($tmpstr) > 0) {
   $str = $tmpstr.$unit[2].$str;
}

echo $str;

//将8位RMB转为汉字
function transfer($money, &$str = '', $startUnit = 2, $endUnit = 6)
{
    global $num_to_word, $unit;  //数字数组和单位数组
    if ($money == 0) {
        return ;
    }
    $tmp = $money % 10;
    if ($tmp !== 0) {
        $tmpStr = $num_to_word[$tmp];
        if ($startUnit !==2 ) {
            $tmpStr = $tmpStr.$unit[$startUnit];
        }
    } else {
        $tmpStr = $num_to_word[0];
    }
    $str = $tmpStr.$str;
    $money = floor($money / 10);
    if($startUnit > 6) {
        $startUnit = 3;
    }
    $startUnit++;
    if($startUnit > 6) {
        $startUnit = 3;
        $str = $unit[6].$str;
    }
    transfer($money, $str, $startUnit);
}

  

编程新手,如有错误,欢迎指出。

 

posted @ 2018-04-14 14:07  cherishFree  阅读(1079)  评论(0编辑  收藏  举报