当数据有点混乱时使用 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 库可能更可靠。
目前我正在处理的文本是具有某种标准格式的日期,但是数据不是很干净。
例如,文本可以采用以下格式:
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 库可能更可靠。