使用Ruby测试字符串是否基本上是引号中的整数?

时间:2009-08-05 21:28:21

标签: ruby

我需要一个函数,is_an_integer,其中

"12".is_an_integer? returns true
"blah".is_an_integer? returns false

我怎么能在红宝石中这样做?我会写一个正则表达式,但我假设有一个帮助,我不知道

21 个答案:

答案 0 :(得分:149)

嗯,这是一个简单的方法:

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

答案 1 :(得分:126)

您可以使用正则表达式。这是@ janm建议的功能。

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  

答案 2 :(得分:62)

您可以使用Integer(str)并查看它是否会加注:

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

附录:应该指出的是,虽然"01"确实会返回,但它不适用于"09",只是因为09不是有效的整数文字。

附录附录:根据@ jason-axelson的评论,将Integer(str)更改为Integer(str, 10),以此来解决此问题。

答案 3 :(得分:22)

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

答案 4 :(得分:21)

你可以做一个班轮:

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

答案 5 :(得分:8)

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. 面向对象,是的。

答案 6 :(得分:6)

最简单的方法是使用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也不错,但会为0

返回Integer nil

答案 7 :(得分:5)

我更喜欢:

配置/初始化/ 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?

答案 8 :(得分:5)

Ruby 2.6.0启用casting to an integer without raising an exception,如果强制转换失败,将返回nil。而且由于nil在Ruby中的行为大致类似于false,因此您可以轻松地检查整数,如下所示:

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

答案 9 :(得分:3)

个人我喜欢异常方法,虽然我会稍微考虑一下。

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

然而,正如其他人已经说过,这对八进制字符串不起作用......

答案 10 :(得分:3)

  def isint(str)
    return !!(str =~ /^[-+]?[1-9]([0-9]*)?$/)
  end

答案 11 :(得分:3)

更简单的方法可能是

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

答案 12 :(得分:2)

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

答案 13 :(得分:2)

可能不适合所有情况,只需简单

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

也可能对某些人有用。

因此,如果它是一个数字而不是0,它将返回一个数字。如果它返回0,则它是一个字符串或0.

答案 14 :(得分:2)

<强>解决方案:

# /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)+$/ regex 表达式,用于查找任何字符串中的数字。您可以在http://rubular.com/
  • 上测试正则表达式和结果
  • 我们将它保存在常量IntegerRegex中,以避免每次在方法中使用时都进行不必要的内存分配。
  • integer?是一种疑问方法,应该返回truefalse
  • match是字符串上的一个方法,它根据参数中给定的正则表达式匹配事件,并返回匹配的值或nil
  • !!match方法的结果转换为等效的布尔值。
  • 声明现有String类中的方法是猴子修补,它不会改变现有String功能中的任何内容,只是在任何String对象上添加另一个名为integer?的方法。

答案 15 :(得分:1)

对于更一般化的案例(包括带小数点的数字), 您可以尝试以下方法:

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

有关此处涉及的正则表达式的详细说明,请查看this blog article:)

答案 16 :(得分:0)

扩展@rado的答案,也可以使用三元语句强制返回真假布尔而不使用双重刘海。当然,双逻辑否定版本更简洁,但对于新手来说可能更难阅读(像我一样)。

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

答案 17 :(得分:-1)

string.rb

中的一个班轮
def is_integer?; true if Integer(self) rescue false end

答案 18 :(得分:-1)

我直接喜欢以下内容:

def is_integer?(str)
  str.to_i != 0 || str == '0' || str == '-0'
end

is_integer?('123')
=> true

is_integer?('sdf')
=> false

is_integer?('-123')
=> true

is_integer?('0')
=> true

is_integer?('-0')
=> true

请注意:

is_integer?('123sdfsdf')
=> true

答案 19 :(得分:-2)

当我问这个问题时,我不确定这是不是... 对于任何偶然发现这篇文章的人来说,最简单的方法是

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?将适用于任何对象!

答案 20 :(得分:-3)

你可以使用is_a吗?方法。 例如。 1.is_a?整数将返回true