Class: StringToNumber::ToNumber
- Inherits:
-
Object
- Object
- StringToNumber::ToNumber
- Defined in:
- lib/string_to_number/to_number.rb
Overview
ToNumber class handles the conversion of French text to numbers It uses a complex recursive parsing algorithm to handle French number grammar
Constant Summary collapse
- EXCEPTIONS =
EXCEPTIONS contains direct mappings from French words to their numeric values This includes:
-
Basic numbers 0-90
-
Feminine forms (“une” for “un”)
-
Regional variations (Belgian/Swiss French: “septante”, “huitante”, “nonante”)
-
Special cases for “quatre-vingt” variations with/without ‘s’
-
Compound numbers like “dix-sept”, “soixante-dix”
-
{ 'zéro' => 0, # Zero with accent 'zero' => 0, # Zero without accent 'un' => 1, # Masculine "one" 'une' => 1, # Feminine "one" 'deux' => 2, 'trois' => 3, 'quatre' => 4, 'cinq' => 5, 'six' => 6, 'sept' => 7, 'huit' => 8, 'neuf' => 9, 'dix' => 10, 'onze' => 11, 'douze' => 12, 'treize' => 13, 'quatorze' => 14, 'quinze' => 15, 'seize' => 16, 'dix-sept' => 17, # Compound: "ten-seven" 'dix-huit' => 18, # Compound: "ten-eight" 'dix-neuf' => 19, # Compound: "ten-nine" 'vingt' => 20, 'trente' => 30, 'quarante' => 40, 'cinquante' => 50, 'soixante' => 60, 'soixante-dix' => 70, # Standard French: "sixty-ten" 'septante' => 70, # Belgian/Swiss French alternative 'quatre-vingts' => 80, # Standard French: "four-twenties" (plural) 'quatre-vingt' => 80, # Standard French: "four-twenty" (singular) 'huitante' => 80, # Swiss French alternative 'quatre-vingt-dix' => 90, # Standard French: "four-twenty-ten" 'quatre-vingts-dix' => 90,# Alternative with plural "vingts" 'nonante' => 90 # Belgian/Swiss French alternative }.freeze
- POWERS_OF_TEN =
POWERS_OF_TEN maps French number words to their power of 10 exponents Used for multipliers like “cent” (10^2), “mille” (10^3), “million” (10^6) Includes both singular and plural forms for proper French grammar Uses French number scale where “billion” = 10^12 (not 10^9 as in English)
{ 'un' => 0, # 10^0 = 1 (ones place) 'dix' => 1, # 10^1 = 10 (tens place) 'cent' => 2, # 10^2 = 100 (hundreds, singular) 'cents' => 2, # 10^2 = 100 (hundreds, plural) 'mille' => 3, # 10^3 = 1,000 (thousands, singular) 'milles' => 3, # 10^3 = 1,000 (thousands, plural) 'million' => 6, # 10^6 = 1,000,000 (millions, singular) 'millions' => 6, # 10^6 = 1,000,000 (millions, plural) 'milliard' => 9, # 10^9 = 1,000,000,000 (French billion, singular) 'milliards' => 9, # 10^9 = 1,000,000,000 (French billion, plural) 'billion' => 12, # 10^12 = 1,000,000,000,000 (French trillion, singular) 'billions' => 12, # 10^12 = 1,000,000,000,000 (French trillion, plural) 'trillion' => 15, # 10^15 (French quadrillion, singular) 'trillions' => 15, # 10^15 (French quadrillion, plural) # Extended list of large number names for completeness 'quadrillion' => 15, 'quintillion' => 18, 'sextillion' => 21, 'septillion' => 24, 'octillion' => 27, 'nonillion' => 30, 'decillion' => 33, 'undecillion' => 36, 'duodecillion' => 39, 'tredecillion' => 42, 'quattuordecillion' => 45, 'quindecillion' => 48, 'sexdecillion' => 51, 'septendecillion' => 54, 'octodecillion' => 57, 'novemdecillion' => 60, 'vigintillion' => 63, 'unvigintillion' => 66, 'duovigintillion' => 69, 'trevigintillion' => 72, 'quattuorvigintillion' => 75, 'quinvigintillion' => 78, 'sexvigintillion' => 81, 'septenvigintillion' => 84, 'octovigintillion' => 87, 'novemvigintillion' => 90, 'trigintillion' => 93, 'untrigintillion' => 96, 'duotrigintillion' => 99, 'googol' => 100 # Special case: 10^100 }.freeze
Instance Attribute Summary collapse
-
#keys ⇒ Object
Returns the value of attribute keys.
-
#sentence ⇒ Object
Returns the value of attribute sentence.
Instance Method Summary collapse
-
#initialize(sentence = '') ⇒ ToNumber
constructor
Initialize the ToNumber parser with a French sentence.
-
#to_number ⇒ Integer
Main entry point to convert the French sentence to a number.
Constructor Details
#initialize(sentence = '') ⇒ ToNumber
Initialize the ToNumber parser with a French sentence
108 109 110 111 112 113 114 115 116 117 |
# File 'lib/string_to_number/to_number.rb', line 108 def initialize(sentence = '') # Create regex pattern from POWERS_OF_TEN keys, excluding 'un' and 'dix' # which are handled differently in the parsing logic # Sort keys by length (longest first) to ensure longer matches are preferred # This prevents "cent" from matching before "cents" in "cinq cents" sorted_keys = POWERS_OF_TEN.keys.reject { |k| %w[un dix].include?(k) }.sort_by(&:length).reverse @keys = sorted_keys.join('|') # Create regex alternation pattern # Normalize input to lowercase for case-insensitive matching @sentence = sentence&.downcase || '' end |
Instance Attribute Details
#keys ⇒ Object
Returns the value of attribute keys.
7 8 9 |
# File 'lib/string_to_number/to_number.rb', line 7 def keys @keys end |
#sentence ⇒ Object
Returns the value of attribute sentence.
7 8 9 |
# File 'lib/string_to_number/to_number.rb', line 7 def sentence @sentence end |
Instance Method Details
#to_number ⇒ Integer
Main entry point to convert the French sentence to a number
121 122 123 |
# File 'lib/string_to_number/to_number.rb', line 121 def to_number extract(@sentence, keys) end |