IT story

Ruby를 사용하여 문자열이 기본적으로 따옴표로 묶인 정수인지 테스트하는 방법

hot-time 2020. 7. 8. 07:38
반응형

Ruby를 사용하여 문자열이 기본적으로 따옴표로 묶인 정수인지 테스트하는 방법


함수가 필요합니다 is_an_integer.

  • "12".is_an_integer? true를 반환합니다.
  • "blah".is_an_integer? false를 반환합니다.

루비에서 어떻게해야합니까? 나는 정규 표현식을 작성하지만 내가 알지 못하는 도우미가 있다고 가정합니다.


정규식을 사용할 수 있습니다. 다음은 @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  

다음은 쉬운 방법입니다.

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

사용 Integer(str)하고 발생하는지 확인할 수 있습니다 .

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

이것은에 대해 true를 반환하지만 , 유효한 정수 리터럴이 아니기 때문에에 "01"대해 true를 반환 하지 않습니다 . 이것이 원하는 동작이 아닌 경우 에 두 번째 인수로 추가 할 수 있으므로 숫자는 항상 기본 10으로 해석됩니다."09"0910Integer


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

하나의 라이너를 사용할 수 있습니다.

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

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

또는

int = Integer(str) rescue false

수행하려는 작업에 따라 rescue 절과 함께 begin end block을 직접 사용할 수도 있습니다.

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

  i.times do |j|
    puts j
  end
rescue ArgumentError
  puts "Not an int, doing something else"
end

Ruby 2.6.0 에서는 예외를 발생시키지 않고 정수로nil 캐스트 할 수 있으며 캐스트가 실패하면 리턴 됩니다. 그리고 nil대부분 false루비 처럼 동작 하기 때문에 다음과 같이 쉽게 정수를 확인할 수 있습니다 :

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
  1. 접두사가 붙지 않습니다 is_. 내가 좋아하는,와 Questionmark 방법에 대한 그 바보 I을 찾아 "04".integer?더 나은보다 훨씬 "foo".is_integer?.
  2. sepp2k의 합리적인 솔루션을 사용합니다 "01".
  3. 객체 지향, 예.

가장 간단한 방법은 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

개인적으로 나는 예외 접근 방식을 좋아하지만 조금 더 간결하게 만들 것입니다.

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

그러나 다른 사람들이 이미 언급했듯이 이것은 8 진수 문자열에서는 작동하지 않습니다.


루비 2.4 갖는다 Regexp#match?: (a 함께 ?)

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

이전 루비 버전에는이 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

This might not be suitable for all cases simplely using:

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

might also do for some.

If it's a number and not 0 it will return a number. If it returns 0 it's either a string or 0.


Here's my solution:

# /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

And here's how it works:

  • /^(\d)+$/is regex expression for finding digits in any string. You can test your regex expressions and results at http://rubular.com/.
  • We save it in a constant IntegerRegex to avoid unnecessary memory allocation everytime we use it in the method.
  • integer? is an interrogative method which should return true or false.
  • match is a method on string which matches the occurrences as per the given regex expression in argument and return the matched values or nil.
  • !! converts the result of match method into equivalent boolean.
  • And declaring the method in existing String class is monkey patching, which doesn't change anything in existing String functionalities, but just adds another method named integer? on any String object.

Expanding on @rado's answer above one could also use a ternary statement to force the return of true or false booleans without the use of double bangs. Granted, the double logical negation version is more terse, but probably harder to read for newcomers (like me).

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

For more generalised cases (including numbers with decimal point), you can try the following method:

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

You can test this method in an irb session:

(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

For a detailed explanation of the regex involved here, check out this blog article :)


I like the following, straight forward:

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

Careful though:

is_integer?('123sdfsdf')
=> true

One liner in string.rb

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

I'm not sure if this was around when this question is asked but for anyone that stumbles across this post, the simplest way is:

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? will work with any object.

참고URL : https://stackoverflow.com/questions/1235863/how-to-test-if-a-string-is-basically-an-integer-in-quotes-using-ruby

반응형