问题
Right now I'm building a small app that imports data from a spreadsheet and due to the nature of the original entry, there is a string being read in that has values such as 8½, 2½, etc.
My goal with a simple function is to convert 2½ into float 2.5, for example.
I've tried the .to_f method but that has left me with a weird value of 2.02½.
Any insight or suggestions here would be very much appreciated!
回答1:
Unicode only supports a small number of vulgar fractions so a simple lookup table will do the trick:
# 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,
}
Then, a little bit of regex wrangling to pull your "number" apart:
s = "2½"
_, int_part, vulgar_part = *s.match(/(\d+)?(\D+)?/)
And finally, put them together taking care to properly deal with possible nils from the regex:
float_version = int_part.to_i + vulgar_to_float[vulgar_part].to_f
Remember that nil.to_i is 0 and nil.to_f is 0.0.
回答2:
Substitute the halves with ".5"
input = "2½"
input.gsub!("½", ".5")
input.to_f # => 2.5
As an aside, make sure you really want to use floats and not something like BigDecimal.
Here is a page explaining the problem with floats (it's Python, but Ruby and many other languages represent floats the same way, and thus have the same issues).
回答3:
Similar to @muistooshort's answer, I'd use a hash as a lookup table, but I'd take advantage of sub:
# encoding: UTF-8
LOOKUP = {
"½" => 1.0/2,
# ...
"⅞" => 7.0/8,
}
LOOKUP_REGEX = Regexp.union(LOOKUP.keys) # => /½|⅞/
'2½'.sub(LOOKUP_REGEX) { |m| LOOKUP[m].to_s[1..-1] } # => "2.5"
'2⅞'.sub(LOOKUP_REGEX) { |m| LOOKUP[m].to_s[1..-1] } # => "2.875"
To make it more convenient and prettier:
class String
def v_to_f
sub(LOOKUP_REGEX) { |m| LOOKUP[m].to_s[1..-1] }
end
end
'2½'.v_to_f # => "2.5"
'2⅞'.v_to_f # => "2.875"
来源:https://stackoverflow.com/questions/9051560/converting-string-2%c2%bd-two-and-a-half-into-2-5