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

Zac*_*iro 12 ruby string floating-point ruby-on-rails character-encoding

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

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

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

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

mu *_*ort 13

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,
}
Run Code Online (Sandbox Code Playgroud)

然后,一点点正则表达式争吵将你的"数字"分开:

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

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

float_version = int_part.to_i + vulgar_to_float[vulgar_part].to_f
Run Code Online (Sandbox Code Playgroud)

记住那nil.to_i0nil.to_f现在0.0.

  • @Joe:什么是``\ u2189"`?零.所以它对结果没有影响.并且在Unicode中只有[19个粗俗分数](ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt),罗马数字和其他数字形式与此问题无关. (5认同)

Jos*_*eek 6

用一半替换一半 ".5"

input = "2½"
input.gsub!("½", ".5")
input.to_f # => 2.5
Run Code Online (Sandbox Code Playgroud)

顺便说一句,确保你真的想要使用浮点数,而不是像BigDecimal那样.

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

  • 具体化使其易于理解.它比任何其他答案都容易理解.无论如何,没有指定一般问题,所以一般的答案必须是猜测.对需求的猜测在历史上是不可靠的(想想YAGNI和"最可能有效的东西"). (2认同)