제로를 가질 수있는 문자열에서 숫자를 어떻게 구문 분석합니까?
문제
루비에서는 다음 형식으로 날짜를 구문 분석하고 있습니다. 24092008. 각 섹션 (연도, 월, 날짜)을 숫자로 변환하고 싶습니다.
정수 생성자로 전달하는 세 가지 문자열을 생성하는 정규식을 사용하여 나누었습니다.
date =~ /^([\d]{2})([\d]{2})([\d]{4})/
year = Integer($3)
month = Integer($2)
day = Integer($1)
월 라인에 도달하면 다음과 같이 충돌합니다.
`Integer': invalid value for Integer: "09" (ArgumentError)
Octal과 09가 유효한 10 대 숫자가 아니기 때문에 주요 0을 해석하고 있다는 것을 깨닫는 데 시간이 걸렸습니다 ( "07"에서 잘 작동합니다).
이에 대한 우아한 해결책이 있습니까? 아니면 10 미만의 숫자를 테스트하고 먼저 0을 제거해야합니까?
감사.
해결책
나는 Regexes에 익숙하지 않으므로이 답변이 오프베이스라면 용서해주십시오. 나는 $ 3, $ 2 및 $ 1이 끈이라고 가정했습니다. 문제를 복제하기 위해 IRB에서 한 일은 다음과 같습니다.
irb(main):003:0> Integer("04")
=> 4
irb(main):004:0> Integer("09")
ArgumentError: invalid value for Integer: "09"
from (irb):4:in `Integer'
from (irb):4
from :0
그러나 .to_i는 같은 문제가없는 것 같습니다.
irb(main):005:0> "04".to_i
=> 4
irb(main):006:0> "09".to_i
=> 9
다른 팁
기본 10을 지정하십시오
루비에게 문자열을 기본 10 숫자로 해석하고 싶다고 명시 적으로 말하십시오.
Integer("09", 10) # => 9
이것은 보다 낫다 .to_i
엄격하고 싶다면.
"123abc".to_i # => 123
Integer("123abc", 10) # => ArgumentError
내가 이것을 어떻게 알아 냈는지
~ 안에 irb
, method(:Integer)
보고 #<Method: Object(Kernel)#Integer>
. 그것은 나에게 그렇게 말했습니다 Kernel
이 방법을 소유하고 커널에서 문서를 찾았습니다. 메소드 서명 두 번째 인수로서 기반을 취한다는 것을 보여줍니다.
아마도 (0([\d])|([1-9][\d]))
대신에 ([\d]{2})
$ 1, $ 2, $ 3의 대신 $ 2, $ 4 및 $ 5를 사용해야 할 수도 있습니다.
또는 REGEXP가 지원하는 경우 (?:...)
그런 다음 사용하십시오 (?:0([\d])|([1-9][\d]))
Ruby는 Perl에서 Regexp를 가져 오 므로이 후자 버전은 작동해야합니다.