输入具有非日期数值时解析日期时出错

时间:2017-07-22 05:01:39

标签: python python-2.7 parsing python-dateutil datetime-parsing

我正在从具有其他类似日期格式的pdf文档中解析日期

Traceback (most recent call last):
  File "/Users/akjain/Documents/workspace/Parse13F/13FParser.py", line 26, in <module>
    print dparser.parse('  Crl. A. Nos. 291/16, 300/16, 581/16 & 1143/16 Judgment reserved on :   May 31, 2017  ', fuzzy=True)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/parser.py", line 697, in parse
    return DEFAULTPARSER.parse(timestr, **kwargs)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/parser.py", line 303, in parse
    raise ValueError, "unknown string format"
ValueError: unknown string format

我的输入是

print dparser.parse('  Crl. A. Nos. 291/16, 300/16, 581/16 & 1143/16 Judgment reserved on :   May 31, 2017  ', fuzzy=True)

如果我删除&#34; 291 / 16,300 / 16,681 / 16&amp; 1143至1116年&#34;从字符串,代码运行完美。

任何人都可以帮助我解析日期而忽略上述值。

3 个答案:

答案 0 :(得分:1)

可能是因为它在字符串中看到了多个类似日期的组件,所以库感到困惑。如果您知道日期看起来像May 31, 2017并且误报看起来像581/16,那么您可以在执行模糊解析之前将正则表达式应用于字符串以进行清理:

import re

string = '  Crl. A. Nos. 291/16, 300/16, 581/16 & 1143/16 Judgment reserved on :   May 31, 2017  '
string = re.sub('[\d]+/[\d]+', '', s)
print dparser.parse(string, fuzzy=True)

如果您想要定义要解析的日期的结构,则可以以不同的方式使用正则表达式:

import re

s = 'test 234/23/134 234 291/16, 300/16, 581/16 & 1143/16 May 31, 2017 10/15/1997'
match_1 = re.search(r'[A-Za-z]+ [\d]{1,2}, [\d]{4}', s)
print match_1.group(0)
# => May 31, 2017
match_2 = re.search(r'[\d]{2}/[\d]{2}/[\d]{4}', s)
print match_2.group(0)
# => 10/15/1997

您甚至可以将两者结合起来,提取出预期模式在给定行中显示的所有日期:

import re

pattern_1 = r'[A-Za-z]+ [\d]{1,2}, [\d]{4}'
pattern_2 = r'[\d]{2}/[\d]{2}/[\d]{4}'
matches = re.findall(r'{}|{}'.format(pattern_1, pattern_2), s)
print matches
# => ['May 31, 2017', '10/15/1997']

答案 1 :(得分:0)

使用带有try子句的except语句,例如:

try:
    print dparser.parse('...')
except ValueError as ve:
    print('ValueError: {}'.format(ve))

答案 2 :(得分:0)

由于您知道哪种日期格式适用于该解析器,因此您可以使用基于正则表达式的代码将其他日期格式转换为该格式,还可以删除混淆解析器的项目。

在这个解释性示例中,我添加了日期&#39; 23/12 / 2017&#39;在你正在使用的字符串的开头附近。此代码会监视re.sub中指示的模式,并将匹配的字符串传递给processprocess删除由少于三个部分组成的任何内容。然后它尝试从匹配中的三个数字创建一个日期。如果成功,则按输出中的指示格式化此日期,以便解析器能够识别它。我已将箭头库与日期时间一起用于这些日期操作。

>>> import re
>>> s = 'On 23/12/2017  Crl. A. Nos. 291/16, 300/16, 581/16 & 1143/16 Judgment reserved on :   May 31, 2017  '
>>> from datetime import datetime
>>> import arrow
>>> def process(matchobj):
...     items = matchobj.group(0).split('/')[::-1]
...     items = [int(_) for _ in items]
...     if len(items)<3:
...         return ''
...     try:
...         the_date = arrow.get(datetime(*items))
...         return the_date.format('MMMM DD, YYYY')
...     except:
...         return matchobj.group(0)
... 
>>> re.sub(r'(?:\d+/)+\d+', process, s)
'On December 23, 2017  Crl. A. Nos. , ,  &  Judgment reserved on :   May 31, 2017  '