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)

Raises:
  • (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