Question

I have a string Tue 6:30 AM - 12:00 PM, 3:00 PM- 7:00 PM from this I want to get

["Tue", ["6:30 AM - 12:00 PM", "3:00 PM- 7:00 PM"]]

I tried,

(
((?:mon|tue|wed|thu|fri|sat|sun|mo|tu|we|th|fr|sa|su|m|w|f|thurs))  #weekday
\s
( ( (?:\d{1,2}(?:[:]\d{1,2})?)\s*(?:[ap][.]?m.?)  \s*[-|to]+\s*   (?:\d{1,2}(?:[:]\d{1,2})?)\s*(?:[ap][.]?m.?) # hour:min period
    ) ,?\s?
)+
)

But this always giving first duration only, ["Tue", ["3:00 PM- 7:00 PM", "3:00 PM- 7:00 PM"]] I could try to split the duration by comma in program but I don't wish to do so, because there is a way to do it by RegEx itself but I am missing something in my expression.

Was it helpful?

Solution

When you repeat a capturing group, each new repetition will overwrite the previous one. This is normal behaviour in regular expressions in general. Only .NET allows access to each instance ("capture") of a repeated capturing group.

If you know in advance what the maximum number of possible repetitions will be, then you can simply repeat the group "manually" as often as needed.

If you don't know that, use two regexes: Let the first one match from the first to the last time range, and let the second one (applied to the first match using finditer()) match one single range repeatedly.

OTHER TIPS

Instead of repetition inside the regex, you can make the weekday group optional, repeat using findall and construct the result in a loop:

import re

regex = re.compile(r'''
    (?:(mon|tue|wed|thu|fri|sat|sun|mo|tu|we|th|fr|sa|su|m|w|f|thurs)\s*)?  #weekday
    ( (?:\d{1,2}(?:[:]\d{1,2})?)\s*(?:[ap][.]?m.?)  \s*[-|to]+\s*   (?:\d{1,2}(?:[:]\d{1,2})?)\s*(?:[ap][.]?m[.]?) # hour:min period
    )''', 
    re.VERBOSE | re.IGNORECASE)

matches = regex.findall("Tue 6:30 AM - 12:00 PM, 3:00 PM- 7:00 PM")
#[('Tue', '6:30 AM - 12:00 PM'), ('', '3:00 PM- 7:00 PM')]

res = []
for day, dur in matches:
    if day:
        res += [day, [dur]]
    else:
        res[-1].append(dur)

print res
#['Tue', ['6:30 AM - 12:00 PM', '3:00 PM- 7:00 PM']]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top