Unicode поддерживает только небольшое количество вульгарных дробей , поэтому простая таблица поиска сделает свое дело:
# You might want to double check this mapping
vulgar_to_float = {
"\u00BC" => 1.0 / 4.0,
"\u00BD" => 1.0 / 2.0,
"\u00BE" => 3.0 / 4.0,
"\u2150" => 1.0 / 7.0,
"\u2151" => 1.0 / 9.0,
"\u2152" => 1.0 /10.0,
"\u2153" => 1.0 / 3.0,
"\u2154" => 2.0 / 3.0,
"\u2155" => 1.0 / 5.0,
"\u2156" => 2.0 / 5.0,
"\u2157" => 3.0 / 5.0,
"\u2158" => 4.0 / 5.0,
"\u2159" => 1.0 / 6.0,
"\u215A" => 5.0 / 6.0,
"\u215B" => 1.0 / 8.0,
"\u215C" => 3.0 / 8.0,
"\u215D" => 5.0 / 8.0,
"\u215E" => 7.0 / 8.0,
"\u2189" => 0.0 / 3.0,
}
Затем, немного ссоры по регулярному выражению, чтобы вытащить ваш номер"apart:
s = "2½"
_, int_part, vulgar_part = *s.match(/(\d+)?(\D+)?/)
И, наконец, соедините их, стараясь правильно разобраться с возможными nil
s из регулярного выражения:
float_version = int_part.to_i + vulgar_to_float[vulgar_part].to_f
Помните, что nil.to_i
равно 0
и nil.to_f
- это 0.0
.