財務系統、支票打印、合同生成常需將阿拉伯數字轉為「壹佰貳拾叁元整」格式。本文收錄四種風格迥異的實現:陣列映射、逐位遞歸、正則修補、JS 移植版,供不同場景選擇。
function toChineseNumber(float $money): string {
$money = round($money, 2);
$nums = ["零","壹","貳","三","肆","伍","陸","柒","捌","玖"];
$units = ["圓","角","分"];
$grades= ["拾","佰","仟","萬","拾","佰","仟","億"];
[$int, $dec] = explode('.', $money, 2);
$dec = array_filter([$dec[1]??'', $dec[0]??'']); // 分、角
$ret = array_merge($dec, [implode('', cnyMapUnit(str_split($int), $grades)), '']);
$ret = implode('', array_reverse(cnyMapUnit($ret, $units)));
return str_replace(array_keys($nums), $nums, $ret);
}
function cnyMapUnit(array $list, array $units): array {
$ul = count($units);
$xs = [];
foreach (array_reverse($list) as $x) {
$l = count($xs);
if ($x != "0" || !($l % 4)) {
$n = ($x=='0'?'':$x) . $units[($l-1)%$ul];
} else {
$n = is_numeric($xs[0][0]??'') ? $x : '';
}
array_unshift($xs, $n);
}
return $xs;
}
echo toChineseNumber(1234567890); // 壹拾貳億三仟肆佰伍拾陸萬柒仟捌佰玖拾圓
function num_to_rmb($num): string {
$c1 = "零壹貳三肆伍陸柒捌玖";
$c2 = "分角元拾佰仟萬拾佰仟億";
$num = round($num, 2) * 100; // 轉分為整數
if (strlen($num) > 10) return "金額太大";
$i = 0; $c = "";
while (true) {
$n = $i==0 ? substr($num, -1) : $num % 10;
$p1 = substr($c1, 3*$n, 3);
$p2 = substr($c2, 3*$i, 3);
if ($n != '0' || in_array($p2, ['億','萬','元'])) {
$c = $p1 . $p2 . $c;
} else {
$c = $p1 . $c;
}
$i++; $num = (int)($num/10);
if ($num == 0) break;
}
// 合併連續「零」、尾部「零」處理
$j = 0; $slen = strlen($c);
while ($j < $slen) {
$m = substr($c, $j, 6); // UTF-8 一漢字 3 字節
if (in_array($m, ['零元','零萬','零億','零零'])) {
$c = substr($c,0,$j) . substr($c,$j+3);
$j -= 3; $slen -= 3;
}
$j += 3;
}
if (substr($c, -3) == '零') $c = substr($c, 0, -3);
return $c ? $c . "整" : "零元整";
}
echo num_to_rmb(23000000.00); // 貳仟三佰萬元整
function convert_2_cn($num) {
$cn = ["零","壹","貳","三","肆","伍","陸","柒","捌","玖"];
$repair = ['零仟零佰零拾零','萬萬','零仟','零佰','零拾'];
$unit = ["拾","佰","仟","萬","億"];
$exp = ["","萬","億"];
$num = str_pad($num, 12, '-', STR_PAD_LEFT);
$segments = [];
for ($i=12, $k=0; $i>0; $i--) {
if ($i%4==0) $k++;
$segments[$k][] = substr($num, $i-1, 1);
}
$str = '';
foreach ($segments as $k=>$seg) {
if (array_sum($seg)) $str = array_shift($exp) . $str;
foreach ($seg as $nk=>$nv) {
if ($nv=='-') continue;
$str = ($nk==0 ? $cn[$nv] : $cn[$nv].$unit[$nk-1]) . $str;
}
}
$str = str_replace($repair, ['萬','億','-'], $str);
$str = preg_replace("/-{2,}/", "", $str);
return str_replace(['零','-'], ['','零'], $str);
}
// 附贈:中文大寫轉數字
function cn_2_num($str) {
$cn = ["零","壹","貳","三","肆","伍","陸","柒","捌","玖"];
$skip = ["拾","佰","仟"];
$str = str_replace($skip, "", $str);
$len = mb_strlen($str, 'utf-8');
$num = 0; $k = '';
for ($i=0; $i<$len; $i++) {
$ch = mb_substr($str, $i, 1, 'utf-8');
if ($ch=='億') { $num += intval($k)*100000000; $k=''; }
elseif ($ch=='萬') { $num += intval($k)*10000; $k=''; }
else $k .= array_search($ch, $cn);
}
return $num + ($k?intval($k):0);
}
見原文 convertCurrency() + nst_convert(),含前端輸入格式化(千分位、小數位限制)、輸入框聯動演示。