从文本Python识别和提取日期的最佳方法?
nlp
python
7
0

作为我正在从事的大型个人项目的一部分,我试图从各种文本源中分离出内联日期。

例如,我有大量的字符串(通常采用英语句子或语句的形式),采用多种形式:

中央设计委员会会议,星期二10/22 6:30 pm

9/19 LAB:串行编码(第2.2节)

12月15日将举办另一场针对今天无法参加比赛的人。

练习册3(最低工资):于周三9/18 11:59 pm

他将于9月15日出发。

尽管这些日期与自然文本一致,但它们本身都不是采用自然语言形式的(例如,没有“会议将从明天开始两周” —都是明确的)。

作为没有太多此类处理经验的人,什么是最好的起点?我已经研究过诸如dateutil.parser模块和parsedatetime之类的东西,但是这些似乎是您隔离日期之后才进行的。

因此,有什么好的方法可以提取日期和多余的文本

input:  Th 9/19 LAB: Serial encoding (Section 2.2)
output: ['Th 9/19', 'LAB: Serial encoding (Section 2.2)']

或类似的东西?这种处理似乎是由Gmail和Apple Mail之类的应用程序完成的,但是可以用Python实现吗?

参考资料:
Stack Overflow
收藏
评论
共 5 个回答
高赞 时间 活跃
import datefinder
string_with_dates = """
                    entries are due by January 4th, 2017 at 8:00pm
                    created 01/15/2005 by ACME Inc. and associates.
                    """
matches = datefinder.find_dates(string_with_dates)
for match in matches:
    print match
收藏
评论

如果您可以识别实际包含日期信息的段,则可以使用parsedatetime对其进行解析。不过,有几件事情要考虑,即您的约会没有年份,因此您应该选择一个语言环境。

>>> import parsedatetime
>>> p = parsedatetime.Calendar()
>>> p.parse("December 15th")
((2013, 12, 15, 0, 13, 30, 4, 319, 0), 1)
>>> p.parse("9/18 11:59 pm")
((2014, 9, 18, 23, 59, 0, 4, 319, 0), 3)
>>> # It chooses 2014 since that's the *next* occurence of 9/18

当您有多余的文字时,它并不总是能完美地工作。

>>> p.parse("9/19 LAB: Serial encoding")
((2014, 9, 19, 0, 15, 30, 4, 319, 0), 1)
>>> p.parse("9/19 LAB: Serial encoding (Section 2.2)")
((2014, 2, 2, 0, 15, 32, 4, 319, 0), 1)

坦白地说,这似乎是一种简单到足以解析特定格式并从每个句子中选择最可能的问题。除此之外,这将是一个不错的机器学习问题。

收藏
评论

我也在寻找解决方案,但找不到任何解决方案,所以我和一个朋友建立了一个工具来完成此任务。我以为我会回来分享一下,以防其他人觉得有用。

日期查找器-查找并提取文本中的日期

这是一个例子:

import datefinder

string_with_dates = '''
    Central design committee session Tuesday 10/22 6:30 pm
    Th 9/19 LAB: Serial encoding (Section 2.2)
    There will be another one on December 15th for those who are unable to make it today.
    Workbook 3 (Minimum Wage): due Wednesday 9/18 11:59pm
    He will be flying in Sept. 15th.
    We expect to deliver this between late 2021 and early 2022.
'''

matches = datefinder.find_dates(string_with_dates)
for match in matches:
    print(match)
收藏
评论

我很惊讶没有提到SUTimedateparser的search_dates方法。

from sutime import SUTime
import os
import json
from dateparser.search import search_dates

str1 = "Let's meet sometime next Thursday" 

# You'll get more information about these jar files from SUTime's github page
jar_files = os.path.join(os.path.dirname(__file__), 'jars')
sutime = SUTime(jars=jar_files, mark_time_ranges=True)

print(json.dumps(sutime.parse(str1), sort_keys=True, indent=4))
"""output: 
[
    {
        "end": 33,
        "start": 20,
        "text": "next Thursday",
        "type": "DATE",
        "value": "2018-10-11"
    }
]
"""

print(search_dates(str1))
#output:
#[('Thursday', datetime.datetime(2018, 9, 27, 0, 0))]

尽管我已经尝试过其他模块,例如dateutil,datefinder和natty(无法让小鸭使用python),但这两个模块似乎给出了最有希望的结果。

SUTime的结果更可靠,从上面的代码片段可以清楚地看出。但是,SUTime在某些基本情况下会失败,例如解析文本

“直到9/19我都不会上班”

要么

“在9月18日至9月20日之间,我不会上班。

它没有给出第一个文本的结果,而只给出了第二个文本的月份和年份。但是,在search_dates方法中可以很好地处理此问题。 search_dates方法更具攻击性,将提供与输入文本中任何单词相关的所有可能日期。

我还没有找到一种方法来严格解析search_methods中日期的文本。如果我能找到解决方法,那将是我在SUTime上的第一选择,并且如果找到它,我还将确保更新此答案。

收藏
评论

您可以将dateutil模块parse方法与fuzzy选项一起使用。

>>> from dateutil.parser import parse
>>> parse("Central design committee session Tuesday 10/22 6:30 pm", fuzzy=True)
datetime.datetime(2018, 10, 22, 18, 30)
>>> parse("There will be another one on December 15th for those who are unable to make it today.", fuzzy=True)
datetime.datetime(2018, 12, 15, 0, 0)
>>> parse("Workbook 3 (Minimum Wage): due Wednesday 9/18 11:59pm", fuzzy=True)
datetime.datetime(2018, 3, 9, 23, 59)
>>> parse("He will be flying in Sept. 15th.", fuzzy=True)
datetime.datetime(2018, 9, 15, 0, 0)
>>> parse("Th 9/19 LAB: Serial encoding (Section 2.2)", fuzzy=True)
datetime.datetime(2002, 9, 19, 0, 0)
收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号