编写正则表达式以捕获许多不同的日期格式

时间:2018-11-21 16:03:27

标签: python regex

我正在尝试编写一个正则表达式,它将捕获以下时间格式:

H:MM
HH:MM

,以及在时间之后或之后有空格的P.M或PM的变体,或者小写的形式,或者与AM的变体(希望您有主意)。例如:

1:00PM, 1:00pm, 1pm, 1PM, 1:00 PM, 1:00pm, 2:00

这是我目前拥有的正则表达式:

([0-9]|0[0-9]|1[0-9]|2[0-3])(:[0-5][0-9])?(( )?(PM|AM|am|pm|a.m|p.m|P.M|P.M|a.m.|p.m.|P.M.|A.M.))?

但是,当为我所有的格式工作时,它也会捕获其他所有整数,而我不知道该如何解决。

为解决这个问题,我写了2篇单独的文章,其中一篇只记录了时间:

([0-9]|0[0-9]|1[0-9]|2[0-3])(:[0-5][0-9])

,其中一个仅捕获PM / AM之后的时间:

([0-9]|0[0-9]|1[0-9]|2[0-3])(:[0-5][0-9])?(( )?(PM|AM|am|pm|a.m|p.m|P.M|P.M|a.m.|p.m.|P.M.|A.M.)){1,2}

但理想情况下,我希望对它们全部使用一个表达式,但是我的所有尝试都导致了与本文开头的正则表达式类似的结果。

3 个答案:

答案 0 :(得分:0)

您可以使用此正则表达式:

\d{1,2}:\d{2}(\s*[ap]\.?m\.?)?

说明:

  • \d{1,2}将匹配1或2位数字(一小时)。
  • :将匹配文字:
  • \d{2}将精确匹配2位数字(分钟)。
  • (\s*[ap]\.?m\.?)?:将匹配\s*[ap]\.?m\.?或不匹配,因为括号后有?。现在,让我们分解一下\s*[ap]\.?m\.?
    • \s*将匹配零个或多个空格。 \s表示空白,*表示零个或多个。
    • [ap]将期望ap
    • \.?将与文字.匹配,并且?使其为可选。请注意,正则表达式中的.匹配任何内容,并且要匹配实际的点.,您必须执行\.
    • m将期望m
    • \.?将再次匹配可选的.

并且为了不区分大小写,可以使用IGNORECASE标志编译此正则表达式:

import re
r = re.compile(r'\d{1,2}:\d{2}(\s*[ap]\.?m\.?)?', re.IGNORECASE)

答案 1 :(得分:0)

您可以在python中尝试此正则表达式:/((0\d|1\d|2[0-3]|\d)(((:[0-5]\d))|(\s*[AaPp]\.?[mM]\.?))+)/ 第一部分与小时的第一部分(HH或H)匹配,然后与分钟(如果有)匹配(:MM),最后一个与am,pm及其方差匹配。

演示:https://regex101.com/r/oPb7xb/2

答案 2 :(得分:0)

我知道您明确要求使用正则表达式,但是如果我不指出dateutil解析器是出于某种考虑而编写的,我将不予理会。 (取决于您的最终目标)

在获取奇数日期/时间/日期时间字符串并将其转换为日期时间对象方面做得非常好。

from dateutil.parser import parse

times = [ "1:00PM", "1:00pm", "1pm",  "1PM", "1:00 PM", "1:00 AM", "1:00pm", "2:00"]

for t in times:
    x = parse(t)
    print(f"{x} <--> {t}")

输出:

2018-11-21 13:00:00 <--> 1:00PM
2018-11-21 13:00:00 <--> 1:00pm
2018-11-21 13:00:00 <--> 1pm
2018-11-21 13:00:00 <--> 1PM
2018-11-21 13:00:00 <--> 1:00 PM
2018-11-21 01:00:00 <--> 1:00 AM
2018-11-21 13:00:00 <--> 1:00pm
2018-11-21 02:00:00 <--> 2:00