Answers:
您可以使用正则表达式。这是带有@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
/regexp/ === self
而不是!!(self =~ /regexp/)
构造。你可以用它代替字符类“\ d”[0-9]
好吧,这是简单的方法:
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
self.to_i.to_s == self
为Integer self rescue false
吗?
您可以使用Integer(str)
并查看它是否引发:
def is_num?(str)
!!Integer(str)
rescue ArgumentError, TypeError
false
end
应当指出的是,尽管这确实为true返回true "01"
,但对于却没有返回true "09"
,仅仅是因为它不是09
有效的整数文字。如果这不是您想要的行为,则可以将其添加10
为的第二个参数Integer
,因此该数字始终被解释为以10为底的数字。
#to_i
由于使用方法过于宽泛,因此使用起来太麻烦了。
Integer()
之所以是规范的,是因为Integer ()
您可以确定Ruby认为整数文字的任何内容都会被接受,而其他所有内容都会被拒绝。与使用异常进行控制相比,复制语言已经给您的内容可能会带来更糟糕的代码味道。
您可以做一个班轮:
str = ...
int = Integer(str) rescue nil
if int
int.times {|i| p i}
end
甚至
int = Integer(str) rescue false
根据您要执行的操作,您还可以直接使用带有抢救子句的begin end块:
begin
str = ...
i = Integer(str)
i.times do |j|
puts j
end
rescue ArgumentError
puts "Not an int, doing something else"
end
"12".match(/^(\d)+$/) # true
"1.2".match(/^(\d)+$/) # false
"dfs2".match(/^(\d)+$/) # false
"13422".match(/^(\d)+$/) # true
true
,false
而是MatchData
实例,以及nil
!!
或使用present?
,如果你需要一个布尔!!( "12".match /^(\d)+$/ )
或"12".match(/^(\d)+$/).present?
(后者需要的Rails /的ActiveSupport)
Ruby 2.6.0允许在不引发异常的情况下强制转换为整数,并且nil
如果强制转换失败将返回。并且由于nil
其行为与false
Ruby 相似,因此您可以轻松地检查整数,如下所示:
if Integer(my_var, exception: false)
# do something if my_var can be cast to an integer
end
class String
def integer?
Integer(self)
return true
rescue ArgumentError
return false
end
end
is_
。我发现在问号方法上很愚蠢,我喜欢"04".integer?
比"foo".is_integer?
。"01"
,例如。integer?("a string")
ftl。
String#integer?
是每个Ruby编码器及其表弟都喜欢添加到该语言中的一种常见补丁,从而导致代码库具有三种不同的微妙不兼容的实现以及意外的损坏。我在大型Ruby项目上很难学到这一点。
最好和最简单的方法是使用 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
我更喜欢:
config / initializers / 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?
一个更简单的方法可能是
/(\D+)/.match('1221').nil? #=> true
/(\D+)/.match('1a221').nil? #=> false
/(\D+)/.match('01221').nil? #=> true
def isint(str)
return !!(str =~ /^[-+]?[1-9]([0-9]*)?$/)
end
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
这是我的解决方案:
# /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?
是一种应返回true
或false
。match
是对字符串的方法,该方法根据参数中给定的regex表达式匹配出现的内容,并返回匹配的值或 nil
。!!
将match
方法的结果转换为等效的布尔值。String
类中声明该方法的是猴子补丁,它不会更改现有String功能的任何内容,而只是integer?
在任何String对象上添加另一个命名的方法。对于更一般的情况(包括带小数点的数字),可以尝试以下方法:
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
有关此处涉及的正则表达式的详细说明,请查看此博客文章:)
obj.is_a? String
因为String#to_s会返回自身,我猜与.is_a?
调用相比,不需要太多的处理。这样,您将仅在此行拨打一个电话,而不是一两个。同样,您可以直接将其包含!!
在number?
方法内部,因为按照惯例,以结尾的方法名称?
应该返回布尔值。问候!
我不确定在问这个问题时是否会遇到这种情况,但是对于偶然发现本文的人来说,最简单的方法是:
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?
将适用于任何对象。
"12".is_an_integer? == true
"not12".is_an_integer? == false
12.is_an_integer? == true