サンプル・プログラムの実行例
サンプル・プログラム
num2kanji.php | サンプル・プログラム本体。 |
変換ルール(1)通常記法
0148: /**
0149: * 半角数字を漢数字に変換する(通常記法)
0150: * @param string $instr半角数字
0151: * 小数、負数に対応;指数表記には未対応
0152: * カンマは無視
0153: * @return string漢数字
0154: */
0155: function num2kan_normal($instr) {
0156: static $kantbl = array(0=>'〇', 1=>'一', 2=>'二', 3=>'三', 4=>'四', 5=>'五', 6=>'六', 7=>'七', 8=>'八', 9=>'九', '.'=>'.', '-'=>'-');
0157:
0158: $outstr = '';
0159: $len = strlen($instr);
0160: for ($i = 0; $i < $len; $i++) {
0161: $ch = substr($instr, $i, 1);
0162: if ($ch == ',') continue; //カンマは無視
0163: $outstr .= (isset($kantbl[$ch]) ? $kantbl[$ch] : '');
0164: }
0165:
0166: return $outstr;
0167: }
この処理は、ユーザー関数 num2kan_normal が担当している。
プログラム的には難しいものではない。引数を1文字ずつ取り出して、対応する漢数字に置き換えているだけである。
置換テーブルは連想配列 $kantbl として用意し、変換元文字を添字に、変換後の文字を変数値としている。こういう時に連想配列は便利である。
変換ルール(2)位取り記法
0169: /**
0170: * 半角数字を漢数字に変換する(位取り記法)
0171: * @param string $instr半角数字
0172: * 小数、負数に対応;指数表記には未対応
0173: * カンマは削除
0174: * @return string漢数字
0175: */
0176: function num2kan_decimal($instr) {
0177: static $kantbl1 = array(0=>'', 1=>'一', 2=>'二', 3=>'三', 4=>'四', 5=>'五', 6=>'六', 7=>'七', 8=>'八', 9=>'九', '.'=>'.', '-'=>'-');
0178: static $kantbl2 = array(0=>'', 1=>'十', 2=>'百', 3=>'千');
0179: static $kantbl3 = array(0=>'', 1=>'万', 2=>'億', 3=>'兆', 4=>'京');
0180:
0181: $outstr = '';
0182: $len = strlen($instr);
0183: $m = (int)($len / 4);
0184: //一、万、億、兆‥‥の繰り返し
0185: for ($i = 0; $i <= $m; $i++) {
0186: $s2 = '';
0187: //一、十、百、千の繰り返し
0188: for ($j = 0; $j < 4; $j++) {
0189: $pos = $len - $i * 4 - $j - 1;
0190: if ($pos >= 0) {
0191: $ch = substr($instr, $pos, 1);
0192: if ($ch == ',') continue; //カンマは無視
0193: $ch1 = isset($kantbl1[$ch]) ? $kantbl1[$ch] : '';
0194: $ch2 = isset($kantbl2[$j]) ? $kantbl2[$j] : '';
0195: //冒頭が「一」の場合の処理
0196: if ($ch1 != '') {
0197: if ($ch1 == '一' && $ch2 != '') $s2 = $ch2 . $s2;
0198: else $s2 = $ch1 . $ch2 . $s2;
0199: }
0200: }
0201: }
0202: if ($s2 != '') $outstr = $s2 . $kantbl3[$i] . $outstr;
0203: }
0204:
0205: return $outstr;
0206: }
漢数字の位取りは4桁毎である。すなわち、「一、十、百、千」の4桁で回るループと、その外側の「一、万、億、兆‥‥」の2つの組み合わせからなる。
さらに、一の位以外で「一」があらわれる場合は、これを無視する。「一百万」「一十億」とは記さないからである。
これをプログラムにしたのがユーザー関数 num2kan_decimal である。
正規表現による置換
0291: //変換
0292: if (isButton('exec')) {
0293: //位取記法
0294: if ($mode['decimal'] != '') {
0295: $dest = preg_replace_callback('/[0-9.\.\-\,]+/msu',
0296: function ($mt) {
0297: return num2kan_decimal($mt[0]);
0298: }, $sour
0299: );
0300: //通常記法
0301: } else {
0302: $dest = preg_replace_callback('/[0-9.\.\-\,]+/msu',
0303: function ($mt) {
0304: return num2kan_normal($mt[0]);
0305: }, $sour
0306: );
0307: }
0308: }
関数 preg_replace_callback は、正規表現でマッチした部分文字列をユーザー関数(ここでは num2kan_normal と num2kan_decimal)に渡すことができる。
参考サイト
- PHPで日本語テキストを正規化:ぱふぅ家のホームページ
しかし、スタイルとして縦書き用フォントを適用しても、半角数字を縦書きにすることはできない。組文字を使うなどの手はあるが、やはり漢数字で縦書きにした方が見やすい。
そこで今回は、半角数字を漢数字に変換するPHPプログラムを作ってみることにする。
(2021年5月30日)PHP8対応,リファラ・チェック追加