如何使用 Ruby 测试一个字符串是否基本上是一个引号中的整数

我需要一个函数 is_an_integer

  • "12".is_an_integer?返回 true。
  • "blah".is_an_integer?返回 false。

在 Ruby 我怎么能这么做?我会写一个正则表达式,但我假设有一个我不知道的助手。

135327 次浏览

你可以使用 Integer(str),看看它是否提高:

def is_num?(str)
!!Integer(str)
rescue ArgumentError, TypeError
false
end

需要指出的是,虽然对于 "01"返回 true,但对于 "09"却不是,因为 09不是有效的整数文字。如果这不是您想要的行为,您可以将 10作为第二个参数添加到 Integer,因此数字总是被解释为以10为基数。

简单的办法是:

class String
def is_integer?
self.to_i.to_s == self
end
end


>> "12".is_integer?
=> true
>> "blah".is_integer?
=> false

我不同意那些引起异常来转换字符串的解决方案——异常不是控制流,你最好用正确的方法来做。也就是说,我上面的解决方案不处理非基数为10的整数。因此,这里有一种不诉诸例外的处理方法:

  class String
def integer?
[                          # In descending order of likeliness:
/^[-+]?[1-9]([0-9]*)?$/, # decimal
/^0[0-7]+$/,             # octal
/^0x[0-9A-Fa-f]+$/,      # hexadecimal
/^0b[01]+$/              # binary
].each do |match_pattern|
return true if self =~ match_pattern
end
return false
end
end
class String
def integer?
Integer(self)
return true
rescue ArgumentError
return false
end
end
  1. 它没有以 is_作为前缀。我发现问号方法很傻,我更喜欢 "04".integer?而不是 "foo".is_integer?
  2. 它使用 sepp2k 提供的合理解决方案,该解决方案通过 "01"等。
  3. 面向对象,耶。

可以使用正则表达式。

class String
def is_i?
!!(self =~ /\A[-+]?[0-9]+\z/)
end
end

根据@wich 的评论,这是一个经过编辑的版本:

class String
def is_i?
/\A[-+]?\d+\z/ === self
end
end

以防你只需要检查正数

  if !/\A\d+\z/.match(string_to_check)
#Is not a positive number
else
#Is all good ..continue
end

你可以写一行:

str = ...
int = Integer(str) rescue nil


if int
int.times {|i| p i}
end

甚至

int = Integer(str) rescue false

取决于你正在尝试做什么,你也可以直接使用开始结束块与救援条款:

begin
str = ...
i = Integer(str)


i.times do |j|
puts j
end
rescue ArgumentError
puts "Not an int, doing something else"
end
  def isint(str)
return !!(str =~ /^[-+]?[1-9]([0-9]*)?$/)
end

就我个人而言,我喜欢异常方法,尽管我会使它更简洁一点:

class String
def integer?(str)
!!Integer(str) rescue false
end
end

但是,正如其他人已经指出的,这不适用于八进制字符串。

"12".match(/^(\d)+$/)      # true
"1.2".match(/^(\d)+$/)     # false
"dfs2".match(/^(\d)+$/)    # false
"13422".match(/^(\d)+$/)   # true

Ruby 2.4具有 Regexp#match?: (具有 ?)

def integer?(str)
/\A[+-]?\d+\z/.match? str
end

对于旧的 Ruby 版本,有 Regexp#===。尽管通常应该避免直接使用大小写相等运算符,但这里看起来非常干净:

def integer?(str)
/\A[+-]?\d+\z/ === str
end


integer? "123"    # true
integer? "-123"   # true
integer? "+123"   # true


integer? "a123"   # false
integer? "123b"   # false
integer? "1\n2"   # false

最好和最简单的方法是使用 Float

val = Float "234" rescue nil


Float "234" rescue nil #=> 234.0


Float "abc" rescue nil #=> nil


Float "234abc" rescue nil #=> nil


Float nil rescue nil #=> nil


Float "" rescue nil #=> nil

Integer也很好,但是对于 Integer nil它会返回 0

扩展@rado 上面的答案,还可以使用三元语句来强制返回真或假布尔值,而不需要使用双刘海。当然,双逻辑非版本更简洁,但对于像我这样的新手来说可能更难阅读。

class String
def is_i?
self =~ /\A[-+]?[0-9]+\z/ ? true : false
end
end

这可能不适用于所有情况,只需使用:

"12".to_i   => 12
"blah".to_i => 0

也许对某些人来说。

如果它是一个数字而不是0,它将返回一个数字。如果返回0,那么它要么是一个字符串,要么是0。

一个更简单的方法可以是

/(\D+)/.match('1221').nil? #=> true
/(\D+)/.match('1a221').nil? #=> false
/(\D+)/.match('01221').nil? #=> true

string.rb航班一班

def is_integer?; true if Integer(self) rescue false end

我不确定问这个问题的时候是否还有这个问题,但是 对于任何偶然发现这篇文章的人来说,最简单的方法是:

var = "12"
var.is_a?(Integer) # returns false
var.is_a?(String) # returns true


var = 12
var.is_a?(Integer) # returns true
var.is_a?(String) # returns false

.is_a?可以处理任何对象。

我更喜欢:

Config/initializer/string.rb

class String
def number?
Integer(self).is_a?(Integer)
rescue ArgumentError, TypeError
false
end
end

然后:

[218] pry(main)> "123123123".number?
=> true
[220] pry(main)> "123 123 123".gsub(/ /, '').number?
=> true
[222] pry(main)> "123 123 123".number?
=> false

或查询电话号码:

"+34 123 456 789 2".gsub(/ /, '').number?

对于较一般的情况(包括有小数点的数字) , 你可尝试以下方法:

def number?(obj)
obj = obj.to_s unless obj.is_a? String
/\A[+-]?\d+(\.[\d]+)?\z/.match(obj)
end

您可以在 irb 会话中测试此方法:

(irb)
>> number?(7)
=> #<MatchData "7" 1:nil>
>> !!number?(7)
=> true
>> number?(-Math::PI)
=> #<MatchData "-3.141592653589793" 1:".141592653589793">
>> !!number?(-Math::PI)
=> true
>> number?('hello world')
=> nil
>> !!number?('hello world')
=> false

有关这里涉及的正则表达式的详细说明,请查看 这篇博客文章:)

我的解决办法是:

# /initializers/string.rb
class String
IntegerRegex = /^(\d)+$/


def integer?
!!self.match(IntegerRegex)
end
end


# any_model_or_controller.rb
'12345'.integer? # true
'asd34'.integer? # false

它是这样运作的:

  • /^(\d)+$/正则表达式表达式,用于在任意字符串中查找数字。您可以在 http://rubular.com/上测试正则表达式和结果。
  • 我们将它保存在一个常量 IntegerRegex中,以避免每次在方法中使用它时都进行不必要的内存分配。
  • integer?是一种返回 truefalse的询问方法。
  • match是字符串上的一个方法,它根据参数中给定的正则表达式匹配出现的次数,并返回匹配的值或 nil
  • !!match方法的结果转换为等效的布尔值。
  • 在现有的 String类中声明这个方法是猴子修补,它不会改变现有 String 函数中的任何东西,只是在任何 String 对象上添加另一个名为 integer?的方法。

Ruby 2.6.0启用了 在不引发异常的情况下强制转换为整数,如果强制转换失败,它将返回 nil。而且,由于 nil在 Ruby 中的行为大多与 false相似,所以您可以很容易地检查一个整数,如下所示:

if Integer(my_var, exception: false)
# do something if my_var can be cast to an integer
end