解析工作时间字符串的正则表达式模式
我正在写一个Python库,用来解析不同的工作时间字符串,并把它们转换成标准的时间格式。不过我在处理以下情况时遇到了困难:
我的正则表达式应该能把 Mon - Fri 7am - 5pm Sat 9am - 3pm
这段文字分成 ['Mon - Fri 7am - 5pm ', 'Sat 9am - 3pm']
这样的两部分,但如果中间有个逗号,就应该返回 []
。
而且,逗号可以出现在任何地方,但不能出现在两个工作日和时间段之间。比如说:Mon - Fri 7am - 5pm Sat 9am - 3pm and available upon email, phone call
这段文字应该返回 ['Mon - Fri 7am - 5pm ', 'Sat 9am - 3pm']
。
这是我尝试过的:
import re
pattern = """(
(?:mon|tue|wed|thu|fri|sat|sun|mo|tu|we|th|fr|sa|su|m|w|f|thurs) # Start weekday
\s*[-|to]+\s* # Seperator
(?:mon|tue|wed|thu|fri|sat|sun|mo|tu|we|th|fr|sa|su|^(?![ap])m|w|f|thurs)? # End weekday
\s*[from]*\s* # Seperator
(?:\d{1,2}(?:[:]\d{1,2})?)\s*(?:[ap][.]?m.?) # Start hour
\s*[-|to]+\s* # Seperator
(?:\d{1,2}(?:[:]\d{1,2})?)\s*(?:[ap][.]?m.?) # Close hour
)"""
regEx = re.compile(pattern, re.IGNORECASE|re.VERBOSE)
print re.findall(regEx, "Mon - Fri 7am - 5pm Sat 9am - 3pm")
# output ['Mon - Fri 7am - 5pm ', 'Sat 9am - 3pm']
print re.findall(regEx, "Mon - Fri 7am - 5pm Sat - Sun 9am - 3pm")
# output ['Mon - Fri 7am - 5pm ', 'Sat - Sun 9am - 3pm']
print re.findall(regEx, "Mon - Fri 7am - 5pm, Sat 9am - 3pm")
# expected output []
# but I get ['Mon - Fri 7am - 5pm,', 'Sat 9am - 3pm']
print re.findall(regEx, "Mon - Fri 7am - 5pm , Sat 9am - 3pm")
# expected output []
# but I get ['Mon - Fri 7am - 5pm ', 'Sat 9am - 3pm']
我还在我的正则表达式中尝试了负向前瞻模式。
pattern = """(
(?:mon|tue|wed|thu|fri|sat|sun|mo|tu|we|th|fr|sa|su|m|w|f|thurs)
\s*[-|to]+\s*
(?:mon|tue|wed|thu|fri|sat|sun|mo|tu|we|th|fr|sa|su|^(?![ap])m|w|f|thurs)?
\s*[from]*\s*
(?:\d{1,2}(?:[:]\d{1,2})?)\s*(?:[ap][.]?m.?)
\s*[-|to]+\s*
(?:\d{1,2}(?:[:]\d{1,2})?)\s*(?:[ap][.]?m.?)
(?![^,])
)"""
但是我没有得到预期的结果。我是不是应该明确写代码来检查这个条件?有没有办法只通过修改我的正则表达式,而不需要写额外的条件检查呢?
我还有一个想法,就是如果没有逗号的话,就在两个工作日和时间段之间加上逗号,然后把我的正则表达式改成按逗号分组或分割。比如说:"Mon - Fri 7am - 5pm Sat 9am - 3pm"
可以变成 "Mon - Fri 7am - 5pm, Sat 9am - 3pm"
。
3 个回答
我没法用一个正则表达式搞定这个,真的很难,你的问题挺好的。
我可以帮你实现你需要的功能,但要提醒你,我对此并不太自豪。
假设你有一个函数可以做到这一点……
def sample_funct(unparsed_schedule)
result = []
# Day Pattern
pattern = """
(?:mon|tue|wed|thu|fri|sat|sun|mo|tu|we|th|fr|sa|su|m|w|f|thurs) # Start weekday
\s*[-|to]+\s* # Seperator
(?:mon|tue|wed|thu|fri|sat|sun|mo|tu|we|th|fr|sa|su|^(?![ap])m|w|f|thurs)? # End weekday
\s*[from]*\s* # Seperator
(?:\d{1,2}(?:[:]\d{1,2})?)\s*(?:[ap][\.]?m\.?) # Start hour
\s*[-|to]+\s* # Seperator
(?:\d{1,2}(?:[:]\d{1,2})?)\s*(?:[ap][\.]?m\.?) # Close hour
"""
# No commas pattern
pattern2 = "%s\s*[^,]\s*%s" % (pattern, pattern)
# Actual Regex Pattern Items
schedule = re.compile(pattern, re.IGNORECASE|re.VERBOSE)
remove_comma = re.compile(pattern2, re.IGNORECASE|re.VERBOSE)
# Check we have no commas in the middle
valid_result = re.search(remove_comma, unparsed_schedule)
if valid_result:
# Positive result, return the list with schedules
result = re.findall(schedule, validresult.group(0))
# If no valid results will return empty list
return result
我写了几行代码,用来检查并在每个工作日的时间段之间加上逗号,如果原本没有的话。这样我就能得到一个统一的格式,比如"周一 - 周五 早上7点 - 下午5点, 周六 早上9点 - 下午3点"
,然后我就可以继续进行其他操作了。
我觉得你可以通过匹配整个表达式来简单地做到这一点,这样就不允许出现逗号(以及其他字符):
pattern = """^(
(
(?:mon|tue|wed|thu|fri|sat|sun|mo|tu|we|th|fr|sa|su|m|w|f|thurs) # Start weekday
\s*[-|to]+\s* # Seperator
(?:mon|tue|wed|thu|fri|sat|sun|mo|tu|we|th|fr|sa|su|^(?![ap])m|w|f|thurs)? # End weekday
\s*[from]*\s* # Seperator
(?:\d{1,2}(?:[:]\d{1,2})?)\s*(?:[ap][.]?m.?) # Start hour
\s*[-|to]+\s* # Seperator
(?:\d{1,2}(?:[:]\d{1,2})?)\s*(?:[ap][.]?m.?) # Close hour
)
)+$""
这样会输出:
[('Sat 9am - 3pm', 'Sat 9am - 3pm')]
[('Sat - Sun 9am - 3pm', 'Sat - Sun 9am - 3pm')]
[]
[]
希望这对你有帮助,