Вы можете записать их в массив с помощью scan
, который будет соответствовать всем вхождениям вашего регулярного выражения:
irb(main):001:0> s = 'every 15th of the month'
=> "every 15th of the month"
irb(main):003:0> s2 = 'every 21st and 28th of the month'
=> "every 21st and 28th of the month"
irb(main):004:0> s3 = 'every 21st, 22nd, and 28th of the month'
=> "every 21st, 22nd, and 28th of the month"
irb(main):006:0> myarray = s3.scan(/(\d{1,2}(?:st|nd|rd|th))/)
=> [["21st"], ["22nd"], ["28th"]]
irb(main):007:0> myarray = s2.scan(/(\d{1,2}(?:st|nd|rd|th))/)
=> [["21st"], ["28th"]]
irb(main):008:0> myarray = s.scan(/(\d{1,2}(?:st|nd|rd|th))/)
=> [["15th"]]
irb(main):009:0>
Тогда, конечно, вы можете получить доступ к каждому совпадению с помощью типичной записи myarray[index]
(илиперебрать все из них и т. д.).
Редактировать: Исходя из ваших комментариев, я бы так и сделал:
ORDINALS = (1..31).map { |n| ActiveSupport::Inflector::ordinalize n }
DAY_OF_MONTH_REGEX = /(#{ORDINALS.join('|')})/i
myarray = string.scan(DAY_OF_MONTH_REGEX)
Это действительно только срабатываетвверх по порядковым номерам, которые могут появиться в других фразах.Попытка получить более строгие ограничения, вероятно, будет довольно уродливой, поскольку вам придется охватить кучу разных случаев.Может быть в состоянии что-то придумать ... но это, вероятно, не стоило бы того.Если вы хотите проанализировать строку с действительно детализированным управлением и переменным количеством текста, чтобы соответствовать, то, честно говоря, это, вероятно, просто не работа для регулярных выражений.Трудно быть уверенным, не зная, в каком формате строки, если это происходит из файла с другими подобными строками, если у вас есть какой-либо контроль над форматом / содержимым строк и т. Д.