class ChineseNumber::Parser
Constants
- ARABIC_NUMBER
- DIGIT_MAP
- DIGIT_TOKEN
- MULTIPERS
- MULTIPER_TOKEN
- TOKEN
Attributes
parts[R]
Public Class Methods
generate_base_map()
click to toggle source
# File lib/chinese_number/parser.rb, line 9 def self.generate_base_map chinese_numbers = "一两二三四五六七八九〇零".chars digits = "122345678900".chars.map(&:to_i) Hash.new.tap do |map| chinese_numbers.each_with_index do |w, i| d = digits[i] map[w] = map[d.to_s] = d end end end
generate_multipers_map()
click to toggle source
# File lib/chinese_number/parser.rb, line 20 def self.generate_multipers_map { '十' => 10, '百' => 100, '千' => 1000, '万' => 10000, # “兆” 在各处有不同的意义 # 可能是 “百万”、“万亿”或“万万亿” # see: # http://zh.wikipedia.org/wiki/%E5%85%86 # # 你可以通过这样的方式修改成需要的含义: # # ChineseNumber::Parser::MULTIPERS['兆'] = 10000_0000_0000 '兆' => 100_0000, '亿' => 10000_0000 } end
Public Instance Methods
parse(word)
click to toggle source
# File lib/chinese_number/parser.rb, line 48 def parse word raise InvalidWord unless word =~ /\A#{TOKEN}\Z/ # 类似“二零一二” 这种短语,可以直接拼数字返回 unless word =~ MULTIPER_TOKEN return word.gsub(/\S/) {|w| DIGIT_MAP[w]}.to_i end @scanner = StringScanner.new( word ) @parts = [] while w = @scanner.scan( /\S/ ) case w when ARABIC_NUMBER if @scanner.check(ARABIC_NUMBER) w << @scanner.scan( /\d+/ ) handle_digit w.to_i else handle_digit DIGIT_MAP[w] end when DIGIT_TOKEN handle_digit DIGIT_MAP[w] when MULTIPER_TOKEN handle_multiper MULTIPERS[w] else raise UnexpectToken.new(w) end end parts.reduce(0) do |sum, part| sum + part.to_i end end
Private Instance Methods
handle_digit(num)
click to toggle source
# File lib/chinese_number/parser.rb, line 85 def handle_digit num # 此处处理省略倍数的情况,例如 # "一万五"、"八万八" if @scanner.eos? && parts.last && parts.last.factor >= 10 parts << MultipedNum.new( num, parts.last.factor / 10 ) else parts << MultipedNum.new( num, 1 ) end end
handle_multiper(multiper)
click to toggle source
# File lib/chinese_number/parser.rb, line 95 def handle_multiper multiper if parts.empty? parts << MultipedNum.new( 1, 1 ) end if parts.last.factor <= multiper parts.each do |part| if part.factor <= multiper part.factor *= multiper end end else parts << MultipedNum.new( 1, multiper ) end end