看着它,最简单的方法是修改 dateutil解析器以具有模糊多重选项。
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
迪特的更新
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))
如果要在 parserinfo 上设置选项,请实例化 parserinfo 并将其传递给 parser 对象。例如:
from dateutil.parser import _timelex, parser, parserinfo
info = parserinfo(dayfirst=True)
p = parser(info)