看起来,最不破坏的方法是修改dateutil parser,增加模糊多选项。
parser._parse
接受您的字符串,使用_timelex
对其进行标记化,然后将标记与parserinfo
中定义的数据进行比较。
在这里, 如果一个标记与parserinfo
中的任何内容都不匹配,则解析将失败,除非fuzzy
为True。
我建议您在没有处理过的时间标记时允许非匹配,然后当您遇到非匹配时,在该点处理解析数据并重新开始查找时间标记。
不应该需要太多的努力。
更新
在等待您的补丁被合并时...
这是一个有点hacky的方法,使用了库中非公开的函数,但不需要修改库文件,也不是试错法。如果存在可以转换为浮点数的单独标记,则可能会导致误报。您可能需要进一步过滤结果。
from dateutil.parser import _timelex, parser
a = "I like peas on 2011-04-23, and I also like them on easter and my birthday, the 29th of July, 1928"
p = parser()
info = p.info
def timetoken(token):
try:
float(token)
return True
except ValueError:
pass
return any(f(token) for f in (info.jump,info.weekday,info.month,info.hms,info.ampm,info.pertain,info.utczone,info.tzoffset))
def timesplit(input_string):
batch = []
for token in _timelex(input_string):
if timetoken(token):
if info.jump(token):
continue
batch.append(token)
else:
if batch:
yield " ".join(batch)
batch = []
if batch:
yield " ".join(batch)
for item in timesplit(a):
print "Found:", item
print "Parsed:", p.parse(item)
产出:
发现:2011年04月23日
解析:2011-04-23 00:00:00
发现:1928年7月29日
解析:1928-07-29 00:00:00
Dieter的更新
Dateutil 2.1似乎是为了与python3兼容而编写的,并使用名为six
的"兼容性"库。它对str
对象的处理不正确,不能将其视为文本。
如果您将字符串作为Unicode或类文件对象传递,则此解决方案可与dateutil 2.1一起使用:
from cStringIO import StringIO
for item in timesplit(StringIO(a)):
print "Found:", item
print "Parsed:", p.parse(StringIO(item))
如果您想在解析器信息中设置选项,请实例化一个解析器信息并将其传递给解析器对象。例如:
from dateutil.parser import _timelex, parser, parserinfo
info = parserinfo(dayfirst=True)
p = parser(info)