class Money::Parser::Fuzzy
def self.parse(input, currency = nil, **options)
def self.parse(input, currency = nil, **options) new.parse(input, currency, **options) end
def extract_amount_from_string(input, currency, strict)
def extract_amount_from_string(input, currency, strict) unless input.is_a?(String) return input end if input.strip.empty? return '0' end number = input.scan(NUMERIC_REGEX).flatten.first number = number.to_s.strip if number.empty? if !strict return '0' else raise MoneyFormatError, "invalid money string: #{input}" end end marks = number.scan(/[#{ESCAPED_MARKS}]/).flatten if marks.empty? return number end if marks.size == 1 return normalize_number(number, marks, currency) end # remove end of string mark number.sub!(/[#{ESCAPED_MARKS}]\z/, '') if (amount = number[DOT_DECIMAL_REGEX] || number[INDIAN_NUMERIC_REGEX] || number[CHINESE_NUMERIC_REGEX]) return amount.tr(ESCAPED_NON_DOT_MARKS, '') end if (amount = number[COMMA_DECIMAL_REGEX]) return amount.tr(ESCAPED_NON_COMMA_MARKS, '').sub(',', '.') end if strict raise MoneyFormatError, "invalid money string: #{input}" end normalize_number(number, marks, currency) end
def last_digits_decimals?(digits, marks, currency)
def last_digits_decimals?(digits, marks, currency) # Grouping marks are always different from decimal marks # Example: 1,234,456 *other_marks, last_mark = marks other_marks.uniq! if other_marks.size == 1 return other_marks.first != last_mark end # Thousands always have more than 2 digits # Example: 1,23 must be 1 dollar and 23 cents if digits.last.size < 3 return !digits.last.empty? end # 0 before the final mark indicates last digits are decimals # Example: 0,23 if digits.first.to_i.zero? return true end # The last mark matches the one used by the provided currency to delimiter decimals currency.decimal_mark == last_mark end
def normalize_number(number, marks, currency)
def normalize_number(number, marks, currency) digits = number.rpartition(marks.last) digits.first.tr!(ESCAPED_MARKS, '') if last_digits_decimals?(digits, marks, currency) "#{digits.first}.#{digits.last}" else "#{digits.first}#{digits.last}" end end
def parse(input, currency = nil, strict: false)
-
(MoneyFormatError)
-
Returns:
-
(Money)
-
Parameters:
-
strict
(Boolean
) -- -
currency
(String, Money::Currency, nil
) -- -
input
(String
) --
Deprecated:
- Use {LocaleAware.parse} or {Simple.parse} instead.
def parse(input, currency = nil, strict: false) currency = Money::Helpers.value_to_currency(currency) amount = extract_amount_from_string(input, currency, strict) Money.new(amount, currency) end