如何只在String包含number元素时才将String转换为Number

时间:2015-05-26 05:12:08

标签: ruby

在红宝石nil.to_f"".to_f返回0.0"1foo2".to_f返回1.0。在这些情况下,我想获得nil

我想要的是:

nil.my_to_f #=> nil
"".my_to_f #=> nil
"1foo2".my_to_f #=> nil
"3".my_to_f #=> 3.0
"3.5".my_to_f #=> 3.5

'.3'.my_to_f #=> nil
'.'.my_to_f #=> nil

为了启用此功能,我写道:

match(/^([\d\.]+)$/){ $1.to_f if $1 }

它适用于前五个示例,但最后两个失败。 如何像实例一样将String转换为Float?

如果有宝石,我愿意使用它。

更新

我的代码nil引发错误,抱歉。我会解决它。

2 个答案:

答案 0 :(得分:3)

您可以使用Float课程。请注意,如果值错误,则会引发ArgumentError

def my_to_f(n)
  Float(n)
rescue
  0.0 if n == "."
end

my_to_f nil     #=> nil
my_to_f ""      #=> nil
my_to_f "1foo2" #=> nil
my_to_f "3"     #=> 3.0
my_to_f "3.5"   #=> 3.5
my_to_f ".3"    #=> 0.3
my_to_f "."     #=> 0.0

答案 1 :(得分:1)

你可以这样做:

class NilClass
  def my_to_f
    nil
  end
end

class String
  def my_to_f
    r = /
        ^          # match beginning of string 
        -?         # optionally match minus sign      
        \d+        # match > 0 digits     
        (?:\.\d*)? # optionally match decimal, >= 0 digits in non-capture group
        $          # match end of string
        /x
    s = self[r]
    s ? s.to_f : nil
  end
end

nil.my_to_f      #=> nil
"".my_to_f       #=> nil
"1foo2".my_to_f  #=> nil
"3".my_to_f      #=> 3.0
"3.5".my_to_f    #=> 3.5
".3".my_to_f     #=> nil
".".my_to_f      #=> nil
"3.".my_to_f     #=> 3.0
"-2.4". my_to_f  #=>-2.4

如果您希望"3.".my_to_f返回nil,请将\d*更改为\d+