1

Consider a string like this to extract the time information:

str = "Sun rises at 6:23 am & sets at 5:45 pm; Moon comes up by 7:20 pm and goes down by 3:45 am"

I wish to have an enumerator like scan but one that can get me the MatchData objects instead of arrays as available from scan.

For instance, I can write:

str.scan( /(?<time>\d:\d{2}) (?<meridiem>am|pm)/ ){ |arr| p arr }

to get:

["6:23", "am"] ["5:45", "pm"] ["7:20", "pm"] ["3:45", "am"]

But, I wonder if there something like this:

str.match_all( /(?<time>\d:\d{2}) (?<meridiem>am|pm)/ ){ |md| p md }

to get:

#<MatchData "6:23 am" time:"6:23" meridiem:"am"> #<MatchData "5:45 pm" time:"5:45" meridiem:"pm"> #<MatchData "7:20 pm" time:"7:20" meridiem:"pm"> #<MatchData "3:45 am" time:"3:45" meridiem:"am">

Saw an answer in a previous question, but I feel its an inelegant solution. So checking up in case things have changed over the last couple of years since the answer was posted.

Community
  • 1
  • 1
Jikku Jose
  • 18,306
  • 11
  • 41
  • 61
  • 2
    The accepted answer on the question you referred seems short and quite elegant to me. You can implement this `match_all` based on that. – Guilherme Bernal Oct 25 '13 at 17:56
  • I agree with @Guilherme, but it's been helpful to me to think about your question, and see the earlier answer. – Cary Swoveland Oct 25 '13 at 18:21
  • The accepted answer to the linked question is as elegant as I can think of. If you are not satisfied with even that, then think of a more elegant answer by yourself. Considering your high standards, you should be able to do that by yourself. – sawa Oct 25 '13 at 18:41
  • Thanks everyone; probably you are right! I somehow assumed such a `match_all` method should exist, assuming the requirement to be rather common. I must apologise in using the term "inelegant" for the quoted answer; I was just looking for a rather direct method instead. – Jikku Jose Oct 26 '13 at 11:41

1 Answers1

2

Very identical to the answer you have already seen, but slightly different.

str = "Sun rises at 6:23 am & sets at 5:45 pm; Moon comes up by 7:20 pm ..."
str.gsub(/(?<time>\d:\d{2}) (?<meridiem>am|pm)/).map{ Regexp.last_match } 

#=> [#<MatchData "6:23 am" time:"6:23" meridiem:"am">, #<MatchData "5:45 pm" ...
Bala
  • 11,068
  • 19
  • 67
  • 120
  • I was thinking about a similar solution, but I didn't know `Regexp.last_match` existed. But somehow catching the MatchData from there seems problematic to me, when thinking about its scope. – Jikku Jose Oct 26 '13 at 11:50
  • 2
    Really wished something like `match_all` existed! Quite unbelievable why it doesn't. – Jikku Jose Nov 11 '13 at 07:35