Python - 在字符串中查找日期

时间:2011-07-03 09:45:27

标签: python string date

我希望能够读取字符串并返回其中显示的第一个日期。我可以使用现成的模块吗?我试图为所有可能的日期格式编写正则表达式,但它很长。有没有更好的方法呢?

5 个答案:

答案 0 :(得分:15)

您可以在文本的所有子文件上运行日期解析器并选择第一个日期。当然,这样的解决方案要么捕获不是日期的东西,要么不会捕捉那些或者很可能同时捕获的东西。

让我提供一个使用dateutil.parser来捕捉看起来像日期的内容的例子:

import dateutil.parser
from itertools import chain
import re

# Add more strings that confuse the parser in the list
UNINTERESTING = set(chain(dateutil.parser.parserinfo.JUMP, 
                          dateutil.parser.parserinfo.PERTAIN,
                          ['a']))

def _get_date(tokens):
    for end in xrange(len(tokens), 0, -1):
        region = tokens[:end]
        if all(token.isspace() or token in UNINTERESTING
               for token in region):
            continue
        text = ''.join(region)
        try:
            date = dateutil.parser.parse(text)
            return end, date
        except ValueError:
            pass

def find_dates(text, max_tokens=50, allow_overlapping=False):
    tokens = filter(None, re.split(r'(\S+|\W+)', text))
    skip_dates_ending_before = 0
    for start in xrange(len(tokens)):
        region = tokens[start:start + max_tokens]
        result = _get_date(region)
        if result is not None:
            end, date = result
            if allow_overlapping or end > skip_dates_ending_before:
                skip_dates_ending_before = end
                yield date


test = """Adelaide was born in Finchley, North London on 12 May 1999. She was a 
child during the Daleks' abduction and invasion of Earth in 2009. 
On 1st July 2058, Bowie Base One became the first Human colony on Mars. It 
was commanded by Captain Adelaide Brooke, and initially seemed to prove that 
it was possible for Humans to live long term on Mars."""

print "With no overlapping:"
for date in find_dates(test, allow_overlapping=False):
    print date


print "With overlapping:"
for date in find_dates(test, allow_overlapping=True):
    print date

无论您是否允许重叠,代码的结果都是不足为奇的垃圾。如果允许重叠,您将获得许多无处可见的日期,如果不允许,则会错过文本中的重要日期。

With no overlapping:
1999-05-12 00:00:00
2009-07-01 20:58:00
With overlapping:
1999-05-12 00:00:00
1999-05-12 00:00:00
1999-05-12 00:00:00
1999-05-12 00:00:00
1999-05-03 00:00:00
1999-05-03 00:00:00
1999-07-03 00:00:00
1999-07-03 00:00:00
2009-07-01 20:58:00
2009-07-01 20:58:00
2058-07-01 00:00:00
2058-07-01 00:00:00
2058-07-01 00:00:00
2058-07-01 00:00:00
2058-07-03 00:00:00
2058-07-03 00:00:00
2058-07-03 00:00:00
2058-07-03 00:00:00

基本上,如果允许重叠:

  1. “1999年5月12日”解析为1999-05-12 00:00:00
  2. “1999年5月”被解析为1999-05-03 00:00:00(因为今天是该月的第3天)
  3. 但是,如果不允许重叠,“2009。2058年7月1日”将被解析为2009-07-01 20:58:00,并且没有尝试解析该期限之后的日期。

答案 1 :(得分:2)

据我所知,标准python库中没有这样的模块。有很多不同的日期格式,很难捕捉到它们。如果我是你,我会转向正则表达式。参考this page

答案 2 :(得分:2)

你也可以试试dateutil.parser ...... 没有亲自尝试过,但听到了一些好评。 python-dateutil

答案 3 :(得分:0)

在这里,我想你想用不同的格式(甚至语言)来解析日期。如果您只需要一些文本中的日期字符串,请像其他评论者推荐的那样使用dateutil ...

我之前也有过这个任务,并且我使用pyParsing根据我的要求创建了一个解析器,尽管任何合适的解析器都应该这样做。它比正则表达式更容易阅读,测试和调试。

我确实有一些(虽然糟糕)example code on my blog,旨在找到美国格式和德语格式的日期表达式。它可能不是你需要的,但它可以很好地调整。

答案 4 :(得分:0)

我发现以下内容对于将时间转换为统一格式然后搜索此格式模式非常有用:

来自datetime import datetime

date_object = datetime.strptime('March-1-05','%B-%d-%y')
print date_object.strftime(“%B%d,%Y”)