16
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

アラビア数字文字列を "そのまま読める" 日本語文字列に変換

Last updated at Posted at 2014-07-07

@miyabi787 さんの 「PHPで万とか億とかつける感じの」 にインスパイアされてやってみました。

関数定義

※ 「大数」と無量大数より大きな数を扱う「仏典の数詞」をくっつける解釈は誤りなので修正しました。

これ間違ってます↓
Yahoo!知恵袋 - 「無量大数」の上ってありますか??

通常・現代仮名遣い
function japanese_number_readable_format($amount) {
    static $segment_names = [
          '', '万', '億', '兆', '京', '垓',
        "\xf0\xa5\x9d\xb1", '穰', '溝', '澗', '正', '載',
        '極', '恒河沙', '阿僧祇', '那由他', '不可思議',
    ];
    static $level_names = ['', '十', '百', '千'];
    static $number_names = ['一', '二', '三', '四', '五', '六', '七', '八', '九'];
    if (!(is_int($amount) && $amount >= 0) && !ctype_digit($amount)) {
        throw new InvalidArgumentException('正整数か正整数形式文字列で渡してください');
    }
    $results = [];
    $segments = array_filter(str_split(strrev($amount), 4), 'intval');
    foreach ($segments as $i => $segment) {
        $result = '';
        $numbers = array_filter(str_split($segment));
        foreach ($numbers as $j => $number) {
            $result = 
                ($j !== 0 && $number === '1'
                    ? ''
                    : $number_names[$number - 1])
                . $level_names[$j] . $result
            ;
        }
        if (!isset($segment_names[$i])) {
            return '無量大数';
        }
        $result .= $segment_names[$i];
        $results[] = $result;
    }
    return $results ? implode(array_reverse($results)) : '零';
}
大字・歴史的假名遣ひ
function japanese_historical_number_readable_format($amount) {
    static $segment_names = [
          '', '萬', '億', '兆', '京', '垓',
        "\xe7\xa7\xad", '穰', '溝', '澗', '正', '載',
        '極', '恆河沙', '阿僧祇', '那由他', '不可思議',
    ];
    static $level_names = ['', '拾', '佰', '仟'];
    static $number_names = ['壹', '貮', '參', '肆', '伍', '陸', '柒', '捌', '玖'];
    if (!(is_int($amount) && $amount >= 0) && !ctype_digit($amount)) {
        throw new InvalidArgumentException('正整數か正整數形式文字列で渡し給へ');
    }
    $results = [];
    $segments = array_filter(str_split(strrev($amount), 4), 'intval');
    foreach ($segments as $i => $segment) {
        $result = '';
        $numbers = array_filter(str_split($segment));
        foreach ($numbers as $j => $number) {
            $result = 
                ($j !== 0 && $number === '1'
                    ? ''
                    : $number_names[$number - 1])
                . $level_names[$j] . $result
            ;
        }
        if (!isset($segment_names[$i])) {
            return '無量大數';
        }
        $result .= $segment_names[$i];
        $results[] = $result;
    }
    return $results ? implode(array_reverse($results)) : '零';
}

使用例

printf(
    '今日のテスト%s点だった、やばい(確信)' . PHP_EOL,
    japanese_number_readable_format('8108939311919889464364364114514')
);
printf(
    '本日の試驗%s點にていみじ ― 確信' . PHP_EOL,
    japanese_historical_number_readable_format('8108939311919889464364364114514')
);

今日のテスト八百十穰八千九百三十九𥝱三千百十九垓千九百八十八京九千四百六十四兆三千六百四十三億六千四百十一万四千五百十四点だった、やばい(確信)
本日の試驗捌佰拾穰捌仟玖佰參拾玖秭參仟佰拾玖垓仟玖佰捌拾捌京玖仟肆佰陸拾肆兆參仟陸佰肆拾參億陸仟肆佰拾壹萬肆仟伍佰拾肆點にていみじ ― 確信

16
15
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?