RegEx模式解析工作时间字符串

时间:2013-02-07 08:25:23

标签: javascript python regex datetime python-2.7

我正在编写一个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.?)
(?![^,])
)"""

但我没有得到预期的一个。 我应该明确编写检查条件的代码吗?有没有办法只改变我的正则表达式而不是编写显式条件检查?

我想实现的另一种方法是在逗号不存在的情况下在两个工作日持续时间之间插入逗号,并将我的正则表达式改为group by / split by逗号。 "Mon - Fri 7am - 5pm Sat 9am - 3pm" => "Mon - Fri 7am - 5pm, Sat 9am - 3pm"

3 个答案:

答案 0 :(得分:1)

我认为您可以通过匹配整个表达式来做到这一点,以便逗号(和其他字符不被允许:

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')]
[]
[]

希望它有所帮助,

答案 1 :(得分:0)

如果在两个工作日持续时间之间不存在逗号,我写了几行代码来检查并插入逗号。所以我能够得到相同的格式"Mon - Fri 7am - 5pm, Sat 9am - 3pm",我可以继续前进。

答案 2 :(得分:0)

无法想象如何在一个正则表达式中做到这一点,你很难得到一个很好的问题。 我可以做你需要的,但请注意,我并不以此为荣。

假设你有这样做的功能......

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