0

我有一个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"]]

我试过,

(
((?: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?
)+
)

但这总是只给出第一个持续时间, ["Tue", ["3:00 PM- 7:00 PM", "3:00 PM- 7:00 PM"]] 我可以尝试在程序中用逗号分隔持续时间,但我不希望这样做,因为有一种方法可以RegEx自行完成,但我的表达中遗漏了一些东西。

4

2 回答 2

1

当您重复一个捕获组时,每个新的重复都将覆盖前一个。这通常是正则表达式中的正常行为。只有 .NET 允许访问重复捕获组的每个实例(“捕获”)。

如果您事先知道可能重复的最大次数是多少,那么您可以根据需要简单地“手动”重复该组。

如果您不知道,请使用两个正则表达式:让第一个匹配从第一个到最后一个时间范围,并让第二个(应用于第一个匹配使用finditer())重复匹配一个范围。

于 2013-02-07T12:40:08.913 回答
0

您可以将工作日组设为可选,而不是在正则表达式中重复,重复使用findall并在循环中构造结果:

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']]
于 2013-02-19T14:29:02.213 回答