YaKansuji - もう一つの (やりすぎ) ruby 漢数字ライブラリ
Yet another (ultimate) Japanese Kansuji library for ruby.
YaKansuji は ruby 用の日本語の漢数字ライブラリです。 和暦ライブラリの wareki から派生していますが、アラビア数字混じりの漢数字表記など、もう少し多彩な表現を数値と相互変換することができます。
現状のサポートは日本語で万進な10進数だけです。歴史的に使われたことのあった万万進や他の漢字圏の漢数字はサポートしていません。
機能
- 読み取り: 以下の混在したテキストを数値に変換出来ます
- 漢数字 (二万三千五百六十七)
- 全角数字 (1234)
- 単位なし / ゼロ (一六九〇)
- 位取り (2億0010万 / 千〇〇二)
- 大字 (千皕卅肆)
- カンマ表現 (12,345 / 5億3,456万 / 二万、五十)
- 負数 (マイナス五十)
- 数値から漢数字, 漢字混じり数値文字列フォーマット
- 小数 (分厘毛〜清浄)
- 複数のビルトインフォーマッタ
- フォーマッタプラグイン機構
- (オプション) 標準の String, Numeric クラスの拡張
インストール
Gemfile に以下のようにして、bundle を実行するか、
gem 'ya_kansuji'
もしくは gem コマンドで直接インストールしてください。
$ gem install ya_kansuji
使い方
読み取り (漢数字 → 数値)
YaKansuji.to_i に文字を渡すと数値に変換できます。読み取りに関してはオプションはありません。
YaKansuji.to_i("一〇二四") # => 1024
YaKansuji.to_i("マイナス一〇二四") # => -1024
フォーマット (数値 → 漢数字)
YaKansuji.to_kan に数値を渡すことで、漢数字や漢字混じりの文字列に変換します。
YaKansuji.to_kan(12345) # => 一万二千三百四十五
YaKansuji.to_kan(-12345) # => マイナス一万二千三百四十五
対応する値域は -(10**72 - 1) から 10**72 - 1 です。
数値として整数化した値がこの範囲を超える場合、RangeError が発生します。
小数
Float・Rational・BigDecimal を渡すと、小数の命数法 (分 = 10⁻¹ 〜 清浄 = 10⁻²¹) で小数部を出力します。 10⁻²¹ より小さい部分は四捨五入されます。
YaKansuji.to_kan(0.5) # => "五分"
YaKansuji.to_kan(123.456) # => "百二十三・四分五厘六毛"
YaKansuji.to_kan(3.14159, :judic_v) # => "三・一四一五九"
YaKansuji.to_kan(123.456, :gov) # => "123.456"
YaKansuji.to_kan(1.05, :judic_h) # => "1.05"
Float は to_s の最短表現として解釈されるため、0.1 は正確に「一分」になります。
逆に浮動小数点演算の誤差はそのまま出力されます (0.1 + 0.2 → 0.30000000000000004 → 「三分四弾指」)。
誤差を避けたい場合は Rational か BigDecimal を渡してください。
このさい、2つめの引数にシンボルを渡すことにより、フォーマッタを切り替えることができます。
YaKansuji.to_kan(12340005, :simple) # => "千二百三十四万五"
YaKansuji.to_kan(12340005, :gov) # => "1234万, 5"
YaKansuji.to_kan(12340005, :lawyer) # => "1,234万5"
YaKansuji.to_kan(12340005, :judic_v) # => "一二三四万〇〇〇五"
YaKansuji.to_kan(12340005, :judic_h) # => "1234万0005"
現在あるフォーマッタは以下のとおりです。
simple- 標準 (例: 千二百三十四万五)gov- 「公用文作成の要領」方式 (100億, 30万円 / 5,000)lawyer- 行政司法協会方式 (1,200億 / 2億58万6,300)judic_v- 裁判判例縦書き方式 (一二万〇〇五六)judic_h- 最高裁判例横書き方式 (5万0539)
独自フォーマッタ
YaKansuji#register_formatter を使うと独自のフォーマッタを登録できます。
#call を持つ任意のオブジェクトもしくはブロックを渡します。第1引数に数字、第2引数にオプションが渡ります。
負数を渡した場合も、フォーマッタには絶対値 (非負の値) が渡され、符号 (「マイナス」) は to_kan 側で前置されます。
小数を含む値を渡した場合、フォーマッタには正規化済みの値
(整数なら Integer、小数を含むなら Rational) がそのまま渡ります。
YaKansuji.register_formatter :hoge, -> (num, opts = {}) {
if num == 0; ""
elsif num == 1; "いち"
elsif num == 2; "に"
else; "たくさん"
end
}
YaKansuji.to_kan(2, :hoge) # => "に"
YaKansuji.to_kan(123, :hoge) # => "たくさん"
標準クラス拡張
標準では YaKansuji の特異メソッドを直接呼ぶことで使用できますが、短く書く場合、必要応じてビルトインクラス (String, Numeric) の拡張を使うことができます。
クラス拡張では String#to_i を置き換え、Numeric#to_kan を追加します。
拡張の方法は、Refinements と直接拡張の好きな方を選択できます。
Refinements による拡張
YaKansuji::CoreRefine を using すると、 String#to_i を置き換え、 Numeric#to_kan を追加します。
puts "二万".to_i # => 0
using YaKansuji::CoreRefine
puts "二万".to_i # => 20000
puts 20000.to_kan #= > "二万"
puts 20000.to_kan(:gov) # => "2万"
puts 0.5.to_kan # => "五分"
ちなみに、 to_i に base が渡された場合は、漢数字が解釈されずにビルトインクラスのものが呼ばれます。
using YaKansuji::CoreRefine
puts "12万".to_i # => 120000
puts "12万".to_i(:kansuji) # => 120000
puts "12万".to_i(16) # => 18
メソッド上書き
Refinements を使わずに、全域でビルトインクラスを上書きしたい場合は ya_kansuji/core_ext を読み込んでください。これは破壊的にコアライブラリのメソッドを置き換えるため、影響範囲に注意して下さい。
上書きや提供されるメソッドは Refinements と同じです。
require 'ya_kansuji/core_ext'
bundler を使っている場合は、 Gemfile 中で以下のようにできます。
gem 'ya_kansuji', require: 'ya_kansuji/core_ext'
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/sugi/ya_kansuji.
License
The gem is available as open source under the terms of the MIT License.
Author
Tatsuki Sugiura sugi@nemui.org