Como faço para analisar um número de uma String que pode ter um zero à esquerda?
Pergunta
Em Ruby Eu estou analisando uma data no seguinte formato: 24092008. Eu quero converter cada seção (ano, mês, dia) em um número.
Eu tenho separá-los usando um regex que produz três cordas que estou passando para o construtor Integer.
date =~ /^([\d]{2})([\d]{2})([\d]{4})/
year = Integer($3)
month = Integer($2)
day = Integer($1)
Quando ela atinge a linha mês deixa de funcionar da seguinte forma:
`Integer': invalid value for Integer: "09" (ArgumentError)
Levei um tempo para perceber que ele está interpretando o zero como Octal e 09 não é um número Octal válido (ele funciona bem com "07").
Existe uma solução elegante para isso ou devo apenas de teste para números menores que 10 e remover o primeiro zero?
Graças.
Solução
Eu não estou familiarizado com expressões regulares, então me perdoe se esta resposta é off-base. Eu estive assumindo que US $ 3, $ 2, e US $ 1 são strings. Aqui está o que eu fiz no IRB para replicar o problema:
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
Mas parece que .to_i não tem os mesmos problemas:
irb(main):005:0> "04".to_i
=> 4
irb(main):006:0> "09".to_i
=> 9
Outras dicas
Especifique base 10
Diga Rubi explicitamente que deseja interpretar a string como um número base 10.
Integer("09", 10) # => 9
Esta é melhor do que .to_i
se você quiser ser rigoroso .
"123abc".to_i # => 123
Integer("123abc", 10) # => ArgumentError
Como eu descobri isso
Em irb
, method(:Integer)
retornos #<Method: Object(Kernel)#Integer>
. Que me disse que Kernel
possui este método, e eu olhei para a documentação no Kernel. mostra a assinatura do método que é preciso uma base como o segundo argumento.
Talvez (0([\d])|([1-9][\d]))
no lugar de ([\d]{2})
Você pode ter que usar $ 2, $ 4 e US $ 5 no lugar de $ 1, $ 2, $ 3.
Ou se seus apoios regexp (?:...)
então usar (?:0([\d])|([1-9][\d]))
Desde rubi leva seu regexp de perl, esta última versão deve funcionar.