Мне нужна функция is_an_integer, где
"12".is_an_integer? returns true "blah".is_an_integer? returns false
как я могу сделать это в рубине? я бы написал регулярное выражение, но я предполагаю, что для этого есть помощник, которого я не знаю
def isint(str) return !!(str =~ /^[-+]?[1-9]([0-9]*)?$/) end
лично мне нравится подход исключения, хотя я бы сделал его немного более кратким.
class String def integer?(str) !!Integer(str) rescue false end end
Однако, как уже говорили другие, это не работает с октальными строками ...
Решение:
# /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)+$/
IntegerRegex
integer?
true
false
match
nil
!!
String
Может не подходить для всех случаев, но простой
"12".to_i => 12 "blah".to_i => 0
может также подойти для некоторых.
Так что, если это число, а не 0, оно вернет число. Если он возвращает 0, это либо слово, либо 0.
Ruby 2.4 имеет Regexp#match?: (с ?)
Regexp#match?
?
def integer?(str) /\A[+-]?\d+\z/.match? str end
Для более старых версий Ruby есть Regexp#===. И хотя в целом следует избегать прямого использования оператора равенства регистра, здесь он выглядит очень чисто:
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
Для более обобщенных случаев (включая числа с десятичной точкой), Вы можете попробовать следующий метод:
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
Для подробного объяснения регулярного выражения здесь эта статья блога :)
Расширяя ответ @ rado выше, можно также использовать троичное выражение для принудительного возврата истинных или ложных логических значений без использования двойных ударов. Конечно, версия с двойным логическим отрицанием является более краткой, но, вероятно, труднее читать для новичков (таких как я).
class String def is_i? self =~ /\A[-+]?[0-9]+\z/ ? true : false end 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
Один вкладыш в string.rb
string.rb
def is_integer?; true if Integer(self) rescue false end
вы можете использовать is_a? метод. например 1.is_a? Целое число вернет true