当数据有点混乱时使用 datetime.strptime :额外的空格,Jan 或 January

Using datetime.strptime when data is a little messy : extra spaces, Jan or January

目前我正在处理的文本是具有某种标准格式的日期,但是数据不是很干净。

例如,文本可以采用以下格式:

Jan. 1, 2021 (dot after Jan)
Jan, 1 2021 (comma after Jan)
January, 1 2020 (Full month with comma)
Jan,  1 2020 (two spaces after Jan, instead of one)

我不太确定如何处理这个问题。 我想将这些字符串转换成 2021-01-01 格式。

我的计划是转换为日期时间对象,然后再转换回字符串。

但是在使用strptime的时候,花样貌似需要死板, 并且不允许使用类似正则表达式的模式。

print(datetime.datetime.strptime(timestamp, '%b %d, %Y'))

而不是 '%b|%B\s[.,]?

有人对如何将我的文本转换成年-月-日格式有什么建议吗?

您可以尝试使用 dateutil 库,(它是下载次数最多的 pypi 包之一)

>>> from dateutil import parser
>>>
>>> print(parser.parse("Jan. 1, 2021"))
2021-01-01 00:00:00
>>>
>>> print(parser.parse("Jan, 1 2021"))
2021-01-01 00:00:00
>>>
>>> print(parser.parse("January, 1 2020"))
2020-01-01 00:00:00
>>>
>>> print(parser.parse("Jan,  1 2020"))
2020-01-01 00:00:00

如果你不使用图书馆,你可能会有点野蛮:

def normalise(date):
    month_name, day, year = date.replace(',', '').split()
    short_month_name = month_name[:3]
    return f'{short_month_name} {day} {year}'

用法:

>>> normalise('January, 1 2020')
'Jan 1 2020'

等等

然后用datetime就可以正常解析了。

这是适用于您给出的案例的正则表达式。

import re

pattern = """(?ix)   # ignore case, verbose
   (?P<month>
        jan(uary)?
       |feb(uary)?
       |mar(ch)?
       |apr(il)?
       |may
       |jun(e)?
       |jul(y)?
       |aug(ust)?
       |sep(tember)?
       |oct(ober)?
       |nov(ember)?
       |dec(ember)?
   )
   \D+
   (?P<day>\d(\d)?)
   \D+
   (?P<year>\d\d(\d\d)?)
"""

regex = re.compile(pattern)

testcases = """
Jan. 1, 2021 (dot after Jan)
Jan, 1 2021 (comma after Jan)
January, 1 2020 (Full month with comma)
Jan,  1 2020 (two spaces after Jan, instead of one)
""".strip().splitlines()

for test in testcases:
    print(test, end=' => ')
    m = regex.search(test)
    if m:
        print(m.groupdict())
    else:
        print(m)

输出:

Jan. 1, 2021 (dot after Jan) => {'month': 'Jan', 'day': '1', 'year': '2021'}
Jan, 1 2021 (comma after Jan) => {'month': 'Jan', 'day': '1', 'year': '2021'}
January, 1 2020 (Full month with comma) => {'month': 'January', 'day': '1', 'year': '2020'}
Jan,  1 2020 (two spaces after Jan, instead of one) => {'month': 'Jan', 'day': '1', 'year': '2020'}

也就是说,按照 foxyblue 的建议,使用 dateutil 库可能更可靠。