Проверить, является ли строка в целом целым числом в кавычках, используя Ruby? - PullRequest
120 голосов
/ 06 августа 2009

Мне нужна функция is_an_integer, где

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

как я могу сделать это в рубине? я бы написал регулярное выражение, но я предполагаю, что для этого есть помощник, которого я не знаю

Ответы [ 20 ]

153 голосов
/ 06 августа 2009

Ну, вот простой способ:

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
127 голосов
/ 06 августа 2009

Вы можете использовать регулярные выражения. Вот функция с предложениями @ 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  
62 голосов
/ 06 августа 2009

Вы можете использовать Integer(str) и посмотреть, повысится ли оно:

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

Добавление: следует отметить, что хотя это возвращает true для "01", оно не для "09", просто потому, что 09 не будет действительным целочисленным литералом.

Добавление к добавлению: исправлено это путем изменения Integer(str) на Integer(str, 10), согласно комментарию @ jason-axelson.

23 голосов
/ 08 августа 2013
"12".match(/^(\d)+$/)      # true
"1.2".match(/^(\d)+$/)     # false
"dfs2".match(/^(\d)+$/)    # false
"13422".match(/^(\d)+$/)   # true
22 голосов
/ 06 августа 2009

Вы можете сделать один вкладыш:

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
8 голосов
/ 06 августа 2009
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 голосов
/ 03 января 2019

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
6 голосов
/ 29 ноября 2013

Лучший и простой способ использует 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

5 голосов
/ 12 мая 2016

Я предпочитаю:

конфиг / Инициализаторы / 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?
3 голосов
/ 12 июля 2015

Гораздо проще может быть

/(\D+)/.match('1221').nil? #=> true
/(\D+)/.match('1a221').nil? #=> false
/(\D+)/.match('01221').nil? #=> true
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...