严格地将字符串转换为整数(或 nil)

对于 web 编程来说,数字是以字符串的形式出现的。但是 to_i会将 "5abc"转换为 5,将 "abc"转换为 0,两个答案都是错误的。为了抓住这些,我写道:

def number_or_nil( s )
number = s.to_i
number = nil if (number.to_s != s)
return number
end

有没有一种更简洁、更自然的 Ruby 方式来完成这种转换并检测字符串不是作为数字使用的?

95737 次浏览

使用整数(字符串)

如果字符串不能转换为整数,则会引发 ArgumentError 错误。

Integer('5abc') #=> ArgumentError: invalid value for Integer(): "5abc"
Integer('5') #=> 5

如果您希望在字符串无法转换时返回 nil,那么仍然需要 number _ or _ nil 方法。

def number_or_nil(string)
Integer(string || '')
rescue ArgumentError
nil
end

您应该注意从特定的异常中进行拯救。一个单独的拯救(比如“拯救 nil”)将从从 StandardError 继承的任何错误中拯救出来,并且可能以您意想不到的方式干扰程序的执行。Integer ()将引发 ArgumentError,因此请指定。

如果您不想处理异常,而只是更喜欢 number _ 或 _ nil 的较短版本,那么您可以利用隐式返回值,将其写成:

def number_or_nil(string)
num = string.to_i
num if num.to_s == string
end


number_or_nil '5' #=> 5
number_or_nil '5abc' #=> nil

这就是你想要的结果。

使用一个简单的正则表达式检查 str是一个整数。

def number_or_nil(str)
str.to_i if str[/^-?\d+$/] and str.line.size == 1
end

至少从 Ruby 2.6开始,内核函数 Integer、 Float 等接受一个 exception关键字参数来完成这项工作:

> Integer('42', exception: false)
=> 42
> Integer('x42', exception: false)
=> nil
> Integer('x42')
ArgumentError (invalid value for Integer(): "x42")
> Integer('', exception: false)
=> nil
> Integer('')
ArgumentError (invalid value for Integer(): "")
> Integer(nil, exception: false)
=> nil
> Integer(' 42 ', exception: false)
=> 42
> Integer(' 4 2 ', exception: false)
=> nil

请注意,Integer 还留给您对基函数的控制权,这是 to_i不支持的:

> '0xf'.to_i
=> 0
> Integer('0xf')
=> 15
> Integer('10', 8)
=> 8

当指定基数时,基数前缀(0x...等)必须一致(如果存在) :

> Integer('0xf', 10)
=> ArgumentError(invalid value for Integer(): "0xf")
> Integer('0xf', 16)
=> 15
> Integer('f', 16)
=> 15