class TwitterCldr::Parsers::NumberParser

Constants

SEPARATOR_CHARS

Public Class Methods

is_numeric?(text, separators = SEPARATOR_CHARS) click to toggle source
# File lib/twitter_cldr/parsers/number_parser.rb, line 62
def self.is_numeric?(text, separators = SEPARATOR_CHARS)
  !!(text =~ /\A[0-9#{separators}]+\Z/)
end
new(locale = TwitterCldr.locale, number_system = nil) click to toggle source
# File lib/twitter_cldr/parsers/number_parser.rb, line 17
def initialize(locale = TwitterCldr.locale, number_system = nil)
  @locale = locale
  @data_reader = TwitterCldr::DataReaders::NumberDataReader.new(
    locale, number_system: number_system
  )
end

Public Instance Methods

parse(number_text, options = {}) click to toggle source
# File lib/twitter_cldr/parsers/number_parser.rb, line 24
def parse(number_text, options = {})
  options[:strict] = true unless options.include?(:strict)
  group, decimal = separators(options[:strict])
  tokens = tokenize(number_text, group, decimal)

  num_list, punct_list = tokens.partition { |t| t[:type] == :numeric }
  raise InvalidNumberError unless punct_valid?(punct_list)
  raise InvalidNumberError unless tokens.last && tokens.last[:type] == :numeric

  if punct_list.last && punct_list.last[:type] == :decimal
    result = num_list[0..-2].map { |num| num[:value] }.join.to_i
    result + num_list.last[:value].to_i / (10.0 ** num_list.last[:value].size)
  else
    num_list.map { |num| num[:value] }.join.to_i
  end
end
try_parse(number_text, default = nil, options = {}) { |result| ... } click to toggle source
# File lib/twitter_cldr/parsers/number_parser.rb, line 41
def try_parse(number_text, default = nil, options = {})
  begin
    result = parse(number_text, options)
  rescue InvalidNumberError
    result = nil
  end

  if block_given?
    yield(result)
  else
    result || default
  end
end
valid?(number_text, options = {}) click to toggle source
# File lib/twitter_cldr/parsers/number_parser.rb, line 55
def valid?(number_text, options = {})
  parse(number_text, options)
  true
rescue
  false
end

Protected Instance Methods

decimal_separator() click to toggle source
# File lib/twitter_cldr/parsers/number_parser.rb, line 102
def decimal_separator
  @decimal_separator ||= Regexp.escape(@data_reader.symbols[:decimal])
end
group_separator() click to toggle source
# File lib/twitter_cldr/parsers/number_parser.rb, line 106
def group_separator
  @group_separator ||= Regexp.escape(@data_reader.symbols[:group])
end
identify(text, group, decimal) click to toggle source
# File lib/twitter_cldr/parsers/number_parser.rb, line 86
def identify(text, group, decimal)
  result = { value: text }
  result[:type] = if self.class.is_numeric?(result[:value], "")
    :numeric
  else
    if result[:value] =~ /[#{group}]/
      :group
    elsif result[:value] =~ /[#{decimal}]/
      :decimal
    else
      nil
    end
  end
  result
end
punct_valid?(punct_list) click to toggle source
# File lib/twitter_cldr/parsers/number_parser.rb, line 68
def punct_valid?(punct_list)
  # all group, allowed one decimal at end
  punct_list.each_with_index.all? do |punct, index|
    punct[:type] == :group || (index == (punct_list.size - 1) && punct[:type] == :decimal)
  end
end
separators(strict = false) click to toggle source
# File lib/twitter_cldr/parsers/number_parser.rb, line 75
def separators(strict = false)
  group = strict ? group_separator : SEPARATOR_CHARS
  decimal = strict ? decimal_separator : SEPARATOR_CHARS
  [group, decimal]
end
tokenize(number_text, group, decimal) click to toggle source
# File lib/twitter_cldr/parsers/number_parser.rb, line 81
def tokenize(number_text, group, decimal)
  match_data = number_text.scan(/([\d]*)([#{group}]{0,1})([\d]*)([#{decimal}]{0,1})([\d]*)/)
  (match_data.flatten || []).reject(&:empty?).map { |match| identify(match, group, decimal) }
end