Как проанализировать число из строки, которая может иметь ведущий ноль?

StackOverflow https://stackoverflow.com/questions/146668

  •  02-07-2019
  •  | 
  •  

Вопрос

В Ruby я анализирую дату в следующем формате:24092008.Я хочу преобразовать каждый раздел (год, месяц, дату) в число.

Я разделил их с помощью регулярного выражения, которое создает три строки, которые я передаю в конструктор Integer.

  date =~ /^([\d]{2})([\d]{2})([\d]{4})/
  year = Integer($3)
  month = Integer($2)
  day = Integer($1)

Когда он достигает линии месяца, происходит сбой следующим образом:

`Integer': invalid value for Integer: "09" (ArgumentError)

Мне потребовалось некоторое время, чтобы понять, что он интерпретирует начальный ноль как восьмеричный, а 09 не является допустимым восьмеричным числом (он отлично работает с «07»).

Есть ли элегантное решение этой проблемы или мне следует просто проверить числа меньше 10 и сначала удалить ноль?

Спасибо.

Это было полезно?

Решение

Я не знаком с регулярными выражениями, поэтому простите меня, если этот ответ не соответствует действительности.Я предполагал, что $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

Явно сообщите Ruby, что вы хотите интерпретировать строку как число по основанию 10.

Integer("09", 10) # => 9

Это лучше чем .to_i если хочешь быть строгим.

"123abc".to_i # => 123
Integer("123abc", 10) # => ArgumentError

Как я это понял

В irb, method(:Integer) возвращает #<Method: Object(Kernel)#Integer>.Это сказало мне, что Kernel владеет этим методом, и я поискал документацию по Kernel. Сигнатура метода показывает, что он принимает базу в качестве второго аргумента.

Возможно (0([\d])|([1-9][\d])) на месте ([\d]{2})Возможно, вам придется использовать 2, 4 и 5 долларов вместо 1, 2 и 3 долларов.

Или, если ваше регулярное выражение поддерживает (?:...) затем используйте (?:0([\d])|([1-9][\d]))

Поскольку Ruby берет регулярное выражение из Perl, последняя версия должна работать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top