【问题标题】:How to find dates in the sentence using NLP, RegEx in Python如何在 Python 中使用 NLP、RegEx 查找句子中的日期
【发布时间】:2011-04-18 02:55:31
【问题描述】:

谁能给我一些查找和解析日期的方法(任何格式,“Aug06”、“Aug2006”、“August 2 2008”、“19th August 2006”、“08-06”、“01-08- 06") 在 python 中。

我遇到了这个问题,但它是在 perl... Extract inconsistently formatted date from string (date parsing, NLP)

任何建议都会有所帮助。

【问题讨论】:

    标签: python regex parsing nlp


    【解决方案1】:

    这会找到您例句中的所有日期:

    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 Augst Aug 这样的废话,但因为几乎所有内容都是在您的示例中是可选的,在正则表达式级别您无能为力。

    下一步是将所有匹配项输入解析器,看看它是否可以将它们解析为合理的日期。

    正则表达式无法正确解释上下文。想象一下像You'll find it in box 21. August 3rd will be the shipping date. 这样的(愚蠢的)文本,它会匹配21. August 3rd,这当然是无法解析的。

    【讨论】:

      【解决方案2】:
      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:
              ...
      

      【讨论】:

      • 这不是通用解决方案。
      • 人们希望有一种简单的方法可以关闭“用当前值填补空白”雀跃...“Aug2008”->“2006-08-28”,因为今天是 28 日这个月有点令人难以置信
      • @anand:但他已经很好地回答了问题的一部分——如何解析日期。
      • 写成“01-08-06”的日期可以解释为 8 月 1 日或 1 月 8 日,具体取决于国家/地区。
      • 呃。默认值是从日期时间对象中提取的。没有办法说这一天不见了。 Ugh2:2 位数年份的窗口与当前年份相关 - 对历史数据无用。 Ugh3:YMD/DMY/MDY “优先级”事物不允许检测数据中的混合数据顺序。
      【解决方案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"))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-16
        • 2012-12-22
        • 2019-08-26
        • 1970-01-01
        • 2014-08-24
        相关资源
        最近更新 更多