如何在Python中使用NLP、RegEx查找句子中的日期

如何在Python中使用NLP、RegEx查找句子中的日期,python,regex,parsing,nlp,Python,Regex,Parsing,Nlp,有谁能给我推荐一些在python中查找和解析日期的方法(任何格式,“Aug06”、“Aug2006”、“2008年8月2日”、“2006年8月19日”、“08-06”、“01-08-06”) 我遇到了这个问题,但它是在perl中。。。 任何建议都会有帮助 from dateutil import parser texts = ["Aug06", "Aug2006", "August 2 2008", "19th August 2006", "08-06", "01-08-06"] for

有谁能给我推荐一些在python中查找和解析日期的方法(任何格式,“Aug06”、“Aug2006”、“2008年8月2日”、“2006年8月19日”、“08-06”、“01-08-06”)

我遇到了这个问题,但它是在perl中。。。

任何建议都会有帮助

from dateutil import parser


texts = ["Aug06", "Aug2006", "August 2 2008", "19th August 2006", "08-06", "01-08-06"]
for text in texts:
    print text, parser.parse(text)


Aug06            2010-08-06 00:00:00
Aug2006          2006-08-28 00:00:00
August 2 2008    2008-08-02 00:00:00
19th August 2006 2006-08-19 00:00:00
08-06            2010-08-06 00:00:00
01-08-06         2006-01-08 00:00:00
如果您想在较长的文本中找到这些日期,那么尝试搜索数字组和月份组,并尝试将它们提供给这个解析器。如果文本看起来不像日期,它将抛出异常

months = ['January', 'February',...]
months.extend([mon[:3] for mon in months])

# search for numeric dates:
/[\d \-]+/

# search for dates:
for word in sentence.split():
    if word in months:
        ...

这将查找示例语句中的所有日期:

for match in re.finditer(
    r"""(?ix)             # case-insensitive, verbose regex
    \b                    # match a word boundary
    (?:                   # match the following three times:
     (?:                  # either
      \d+                 # a number,
      (?:\.|st|nd|rd|th)* # followed by a dot, st, nd, rd, or th (optional)
      |                   # or a month name
      (?:(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z]*)
     )
     [\s./-]*             # followed by a date separator or whitespace (optional)
    ){3}                  # do this three times
    \b                    # and end at a word boundary.""", 
    subject):
    # match start: match.start()
    # match end (exclusive): match.end()
    # matched text: match.group()
它绝对不是完美的,可能会错过一些日期(特别是如果它们不是英语的话-
21。Mai 2006
会失败,还有
4ème décembre 1999
),并且会匹配像
August August
这样的废话,但由于在您的示例中几乎所有内容都是可选的,在正则表达式级别,您可以做的事情不多

下一步是将所有匹配项提供给解析器,看看它是否能够将它们解析为合理的日期


正则表达式无法正确解释上下文。想象一个像
这样的(愚蠢的)文本,你会在框21中找到它。8月3日将是发货日期。
它将与
21匹配。8月3日
这当然是无法解析的。

对于您的用例来说,一个很好的选择是“dateutil.parser”,它使用起来非常简单

from dateutil.parser import parse

test_cases = ['15th of April 2020', '06/20/95', '8/2/69', '1/25/2011', '9/3/2002', '4-13-82', 'Mar-02-2009', 'Jan 20, 1974',
              'March 20, 1990', 'Dec. 21, 2001', 'May 25 2009', '01 Mar 2002', '2 April 2003', '20 Aug. 2004',
              '20 November, 1993', 'Aug 10th, 1994', 'Sept 1st, 2005', 'Feb. 22nd, 1988', 'Sept 2002', 'Sep 2002',
              'December, 1998', 'Oct. 2000', '6/2008', '12/2001', '1998', '2002']

for date_string in test_cases:
    print(date_string, parse(date_string).strftime("%Y%m%d"))

这不是一个通用的解决方案。我们希望有一个简单的方法来关闭“用当前值填补缺口”的闹剧。。。“2008年8月”->“2006-08-28”仅仅因为今天是这个月的28日,就有点不对劲了boggler@anand当前位置但他很好地回答了问题的一部分-如何解析日期。写为“01-08-06”的日期可以解释为8月1日或1月8日,具体取决于国家。默认值是从datetime对象提取的。没有办法说那天已经过去了。Ugh2:两位数年份的窗口与当前年份相关——与历史数据无关。Ugh3:YMD/DMY/MDY“优先级”内容不允许检测数据中混合的数据顺序。