라는 문자열 '123'
이 있으며 정수로 변환하고 싶습니다 123
.
나는 당신이 단순히 할 수 있다는 것을 알고 some_string.to_i
있지만 그것은로 변환 'lolipops'
합니다 0
. 이것은 내가 생각한 효과가 아닙니다. 멋지고 고통스러운 잘못된 것을 변환하려고 할 때 얼굴이 터지기를 원합니다 Exception
. 그렇지 않으면, 유효한 0
숫자와 전혀 숫자가 아닌 것을 구별 할 수 없습니다 .
편집 : 정규식 속임수없이 표준 방식을 찾고있었습니다.
답변
루비에는이 기능이 내장되어 있습니다 :
Integer('1001') # => 1001
Integer('1001 nights')
# ArgumentError: invalid value for Integer: "1001 nights"
Joseph Pecoraro의 답변에서 언급했듯이 0x
16 진수 및 0b
2 진수로 시작하는 것과 같이 10 진수가 아닌 유효한 문자열 과 0으로 시작하는 더 까다로운 숫자를 8 진수로 구문 분석 할 수 있습니다.
Ruby 1.9.2는 기수에 대한 두 번째 인수 옵션을 추가하여 위의 문제를 피할 수 있습니다.
Integer('23') # => 23
Integer('0x23') # => 35
Integer('023') # => 19
Integer('0x23', 10)
# => #<ArgumentError: invalid value for Integer: "0x23">
Integer('023', 10) # => 23
답변
이것은 작동 할 수 있습니다 :
i.to_i if i.match(/^\d+$/)
답변
또한 현재 승인 된 솔루션이 16 진, 8 진 및 2 진 숫자 구문 분석에 미칠 수있는 영향에 유의하십시오.
>> Integer('0x15')
# => 21
>> Integer('0b10')
# => 2
>> Integer('077')
# => 63
루비에서 시작 0x
하거나 0X
16 진수 0b
이거나 0B
2 0
진수이며 8 진수입니다. 이것이 원하는 동작이 아닌 경우 문자열을 패턴과 먼저 일치하는지 확인하는 다른 솔루션과 결합 할 수 있습니다. 등 /\d+/
등 정규 표현식,
답변
허용되는 솔루션에 대한 또 다른 예기치 않은 동작 (1.8, 1.9 사용) :
>> Integer(:foobar)
=> 26017
>> Integer(:yikes)
=> 26025
전달되는 내용이 확실하지 않은 경우을 추가해야합니다 .to_s
.
답변
Myron의 답변이 마음에 들지만 “더 이상 Java / C #을 사용하지 않으므로 상속을 다시는 사용하지 않습니다”라는 Ruby 질병으로 고통 받고 있습니다 . 클래스를 열면 위험에 처할 수 있으며 특히 Ruby의 핵심 라이브러리에 포함되어있을 때는 드물게 사용해야합니다 . 나는 그것을 사용하지 않는다고 말하지는 않지만 일반적으로 피하는 것이 쉽고 더 나은 옵션이 있습니다.
class IntegerInString < String
def initialize( s )
fail ArgumentError, "The string '#{s}' is not an integer in a string, it's just a string." unless s =~ /^\-?[0-9]+$/
super
end
end
그런 다음 숫자가 될 수있는 문자열을 사용하려면 수행중인 작업이 명확하고 핵심 클래스를 방해하지 않습니다.
n = IntegerInString.new "2"
n.to_i
# => 2
IntegerInString.new "blob"
ArgumentError: The string 'blob' is not an integer in a string, it's just a string.
이진 숫자 확인 등과 같이 초기화에 다른 모든 검사를 추가 할 수 있습니다. 그러나 가장 중요한 것은 Ruby는 사람들을위한 것이며 사람들을위한 것은 명확성을 의미한다는 것 입니다. 변수 이름 과 클래스 이름을 통해 객체의 이름을 지정하면 훨씬 명확 해집니다.
답변
마지막 프로젝트 에서이 문제를 해결해야했으며 구현은 비슷하지만 약간 다릅니다.
class NotAnIntError < StandardError
end
class String
def is_int?
self =~ /^-?[0-9]+$/
end
def safe_to_i
return self.to_i if is_int?
raise NotAnIntError, "The string '#{self}' is not a valid integer.", caller
end
end
class Integer
def safe_to_i
return self
end
end
class StringExtensions < Test::Unit::TestCase
def test_is_int
assert "98234".is_int?
assert "-2342".is_int?
assert "02342".is_int?
assert !"+342".is_int?
assert !"3-42".is_int?
assert !"342.234".is_int?
assert !"a342".is_int?
assert !"342a".is_int?
end
def test_safe_to_i
assert 234234 == 234234.safe_to_i
assert 237 == "237".safe_to_i
begin
"a word".safe_to_i
fail 'safe_to_i did not raise the expected error.'
rescue NotAnIntError
# this is what we expect..
end
end
end
답변
someString = "asdfasd123"
number = someString.to_i
if someString != number.to_s
puts "oops, this isn't a number"
end
아마도 가장 깨끗한 방법은 아니지만 작동해야합니다.