Python 带有可变文本的 strptime

Python strptime with variable text

我有一个字符串形式的日期列表。它看起来像这样:

[
  "January 29-30 Meeting - 2013",
  "March 19-20 Meeting - 2013",
  "April/May 30-1 Meeting - 2013",
  "June 18-19 Meeting - 2013",
  "July 30-31 Meeting - 2013",
  "September 17-18 Meeting - 2013",
  "October 29-30 Meeting - 2013",
  "December 17-18 Meeting - 2013"
]

我需要将这些日期解析为 datetime 格式。

datetime.strptime("January 29-30 Meeting - 2013", "%B %d-[something] - %Y")
datetime.strptime("January 29-30 Meeting - 2013", "%B [something]-%d [something] - %Y")

有什么方法可以让格式说明符中的 strptime 忽略 [something] 中的文本,因为它可以是可变的?是否有可变文本的格式说明符?

strptime 没有通配符指令。您可以在此处查看指令列表 https://docs.python.org/3/library/time.html#time.strftime

解决问题的明智方法是将正则表达式与 strptime 结合使用。 IE。使用正则表达式过滤掉文本并将剩余的受限文本放入 strptime,或者将匹配的组直接传递到 datetime.

import re
from datetime import datetime

ss = [
  "January 29-30 Meeting - 2013",
  "March 19-20 Meeting - 2013",
  "April/May 30-1 Meeting - 2013",
  "June 18-19 Meeting - 2013",
  "July 30-31 Meeting - 2013",
  "September 17-18 Meeting - 2013",
  "October 29-30 Meeting - 2013",
  "December 17-18 Meeting - 2013"
]

FORMAT = '%B %d %Y'

for s in ss:
    match = re.search(r"(\w+)\s(\d+)-(\d+)\s.*\s(\d{4})", s)
    if match:
        dt1 = datetime.strptime(f'{match.group(1)} {match.group(2)} {match.group(4)}', FORMAT)
        dt2 = datetime.strptime(f'{match.group(1)} {match.group(3)} {match.group(4)}', FORMAT)

        print (dt1, dt2)

请注意,您也有 April/May 30-1 并发症,我没有解决这个问题,因为您没有问这个问题。

作为奖励:

for s in ss:
    match = re.search(r"((\w+)/)?(\w+)\s(\d+)-(\d+)\s.*\s(\d{4})", s)
    if match:
        dt1 = datetime.strptime(
            f'{match.group(2) if match.group(2) else match.group(3)} {match.group(4)} {match.group(6)}', FORMAT)
        dt2 = datetime.strptime(
            f'{match.group(3)} {match.group(5)} {match.group(6)}', FORMAT)

        print (dt1, dt2)

此外,请注意下面@blhsing 提供的有趣但有点老套的解决方案,涉及 _strptime.TimeRE。我不建议做那样的事情,但有趣的是知道你实际上可以那样改变 strptime 本身的行为。

您可以使用延迟匹配任何字符序列的附加指令覆盖 _strptime.TimeRE 对象:

from datetime import datetime
import _strptime
TimeRE = _strptime.TimeRE()
TimeRE.update({'x': '.*?'})
_strptime._TimeRE_cache = TimeRE
print(datetime.strptime("January 29-30 Meeting - 2013", "%B %d-%x - %Y"))

这输出:

2013-01-29 00:00:00