Как мне разобрать число из строки, которая может иметь начальный ноль? - PullRequest
7 голосов
/ 29 сентября 2008

В 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 ]

15 голосов
/ 29 сентября 2008

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

Укажите базу 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. Подпись метода показывает, что она принимает базу в качестве второго аргумента.

1 голос
/ 29 сентября 2008

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...