¿Cómo analizo un número de una cadena que puede tener un cero a la izquierda?
Pregunta
En Ruby estoy analizando una fecha en el siguiente formato:24092008.Quiero convertir cada sección (año, mes, fecha) en un número.
Los he dividido usando una expresión regular que produce tres cadenas que paso al constructor Integer.
date =~ /^([\d]{2})([\d]{2})([\d]{4})/
year = Integer($3)
month = Integer($2)
day = Integer($1)
Cuando llega a la línea del mes, falla de la siguiente manera:
`Integer': invalid value for Integer: "09" (ArgumentError)
Me tomó un tiempo darme cuenta de que está interpretando el cero inicial como octal y 09 no es un número octal válido (funciona bien con "07").
¿Existe una solución elegante para esto o debería simplemente probar los números menores que 10 y eliminar el cero primero?
Gracias.
Solución
No estoy familiarizado con las expresiones regulares, así que perdóname si esta respuesta está fuera de lugar. He estado asumiendo que $ 3, $ 2 y $ 1 son cadenas. Esto es lo que hice en IRB para replicar el 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
Pero parece que .to_i no tiene los mismos problemas:
irb(main):005:0> "04".to_i
=> 4
irb(main):006:0> "09".to_i
=> 9
Otros consejos
Especificar base 10
Dile a Ruby explícitamente que quieres interpretar la cadena como un número base 10.
Integer("09", 10) # => 9
Esto es mejor que .to_i
si quieres ser estricto .
"123abc".to_i # => 123
Integer("123abc", 10) # => ArgumentError
Cómo descubrí esto
En irb
, method(:Integer)
devuelve #<Method: Object(Kernel)#Integer>
. Eso me dijo que Kernel
posee este método, y busqué la documentación en Kernel. La firma del método muestra que se necesita un base como el segundo argumento.
Tal vez (0([\d])|([1-9][\d]))
en lugar de ([\d]{2})
Es posible que tengas que usar $2, $4 y $5 en lugar de $1, $2, $3.
O si su expresión regular es compatible (?:...)
entonces usa (?:0([\d])|([1-9][\d]))
Dado que Ruby toma su expresión regular de Perl, esta última versión debería funcionar.