将字符串“2½”(两个半)转换为2.5

时间:2012-01-29 07:07:12

标签: ruby-on-rails ruby string character-encoding floating-point

现在我正在构建一个从电子表格中导入数据的小应用程序,由于原始条目的性质,读取的字符串具有8½,2½等值。

我使用简单函数的目标是将2½转换为float 2.5,例如。

我尝试过.to_f方法,但这给我留下了奇怪的值2.02½。

非常感谢任何见解或建议!

3 个答案:

答案 0 :(得分:13)

Unicode只支持small number of vulgar fractions,因此一个简单的查找表可以解决这个问题:

# 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,
}

然后,一点点的正则表达式将你的“号码”分开:

s = "2½"
_, int_part, vulgar_part = *s.match(/(\d+)?(\D+)?/)

最后,将它们放在一起,注意正确处理正则表达式中可能的nil

float_version = int_part.to_i + vulgar_to_float[vulgar_part].to_f

请注意nil.to_i0nil.to_f0.0

答案 1 :(得分:6)

".5"

代替两半
input = "2½"
input.gsub!("½", ".5")
input.to_f # => 2.5

顺便说一句,确保你真的想要使用花车而不是BigDecimal之类的东西。

Here是一个解释浮点问题的页面(它是Python,但Ruby和许多其他语言以相同的方式表示浮点数,因此具有相同的问题)。

答案 2 :(得分:2)

与@ muistooshort的答案类似,我会使用哈希作为查找表,但我会利用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" 

使它更方便,更漂亮:

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"