답변:
정규식을 사용할 수 있습니다. 다음은 @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를 반환하지만 , 유효한 정수 리터럴이 아니기 때문에에 "01"
대해 true를 반환 하지 않습니다 . 이것이 원하는 동작이 아닌 경우 에 두 번째 인수로 추가 할 수 있으므로 숫자는 항상 기본 10으로 해석됩니다."09"
09
10
Integer
#to_i
인해 사용 하는 메소드 가 너무 손상되었습니다.
Integer()
때문에 표준 Integer ()
입니다. 언어가 이미 제공 한 것을 복제하는 것은 제어를 위해 예외를 사용하는 것보다 더 나쁜 코드 냄새 일 것입니다.
하나의 라이너를 사용할 수 있습니다.
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
"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?
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
is_
. 내가 좋아하는,와 Questionmark 방법에 대한 그 바보 I을 찾아 "04".integer?
더 나은보다 훨씬 "foo".is_integer?
."01"
.integer?("a string")
ftl.
String#integer?
모든 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
루비 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
다음을 사용하여 모든 경우에 적합하지 않을 수 있습니다.
"12".to_i => 12
"blah".to_i => 0
일부도 할 수 있습니다.
숫자이고 0이 아닌 경우 숫자를 반환합니다. 0을 반환하면 문자열이거나 0입니다.
"12blah".to_i => 12
. 이상한 시나리오에서는 문제가 발생할 수 있습니다.
내 해결책은 다음과 같습니다.
# /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
인수의 주어진 정규 표현식에 따라 발생을 일치시키고 일치하는 값을 반환하는 문자열의 메소드입니다. nil
.!!
match
메소드 의 결과 를 동등한 부울로 변환합니다 .String
클래스 에서 메소드를 선언하는 것은 원숭이 패치입니다. 이것은 기존 문자열 기능에서 아무것도 변경하지 않지만 integer?
String 객체에 이름이 지정된 다른 메소드를 추가 합니다.위의 @rado의 대답을 확장하면 삼중 문을 사용하여 더블 뱅을 사용하지 않고 true 또는 false 부울을 반환 할 수 있습니다. 물론, 이중 논리적 부정 버전은 더 간결하지만 (나 같은) 새로운 이민자에게는 읽기 어려울 것입니다.
class String
def is_i?
self =~ /\A[-+]?[0-9]+\z/ ? true : false
end
end
보다 일반적인 경우 (소수점이있는 숫자 포함)의 경우 다음 방법을 시도 할 수 있습니다.
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
하기 때문에 호출 할 필요가 없으므로 호출에 비해 너무 많은 처리가 필요하지 않습니다 . 이 방법으로이 회선에서 하나 또는 두 개 대신 한 번만 전화를 겁니다. 또한 규칙으로 끝나는 메소드 이름 은 부울 값을 리턴해야하기 때문에 메소드 내부에 직접 포함시킬 수 있습니다 . 문안 인사! .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