2010-05-05 113 views
2

如何从python的文本文件中找到尽可能多的日期模式?日期模式被定义为:某些文本中的日期的python正则表达式

dd mmm yyyy 
^^
    | | 
    +---+--- spaces 

其中:

  • DD是双位数
  • 是三个字符的英文月份名称(如一月,三月,十二月)
  • yyyy是四位数年份
  • 有两个空格作为分隔符

谢谢!

+0

我不跟着你。你是否正在寻找grep的日期模式或日期根据固定的单一模式? – wilhelmtell 2010-05-05 01:30:54

+0

我想提取实际日期。 – ohho 2010-05-05 02:17:02

回答

10

这里找到所有日期符合模式

re.findall(r'\d\d\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s\d{4}', text) 

但对您的问题WilhelmTell的评论后一种方式,我也想知道这是否是你真的要求...

+0

我想要的实际日期。谢谢! – ohho 2010-05-05 02:14:02

0

试试这个:

​​
+1

认真吗? -1?除'\ w \ w \ w'以外的任何其他原因可能不是一种匹配一个月的方式?它**是**他在'dd mmm yyyy'语法中所要求的。尽管这并不理想,但我并不理解downvote。 – dlamotte 2010-05-05 02:04:11

4

这是一个稍微更完整的例子。正则表达式不仅仅匹配有效的日期值。 datetime.strptime将无法​​解析任何无效的内容并引发ValueError。如果日期被解析,那么您有一个完整的datetime对象,可以让您访问许多功能。

>>> from datetime import datetime 
>>> import re 
>>> dates = [] 
>>> patn = re.compile(r'\d{2} \w{3} \d{4}') 
>>> fh = open('inputfile') 
>>> for line in fh: 
... for match in patn.findall(line): 
...  try: 
...  val = datetime.strptime(match, '%d %b %Y') 
...  dates.append(val) 
...  except ValueError: 
...  pass # ignore, this isn't a date 
... 

我想,如果你愿意的话这可以被折叠成与内涵漂亮紧凑的代码。

+0

赞赏!我怎样才能将'val'转换为python中的数组? – ohho 2010-05-05 02:47:10

+1

使用'list.append()'。我更新了片段。 – 2010-05-05 03:55:03

4

使用日历模块,给你一个小的全球意识:

date_expr = r"\d{2} (?:%s) \d{4}" % '|'.join(calendar.month_abbr[1:]) 
print date_expr 
print re.findall(date_expr, source_text) 

对于我来说,这将创建像date_expr:

"\d{2} (:?Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{4}" 

但如果我更改使用本地化模块我的语言环境:

locale.setlocale(0, "fr") 

我现在在法国寻找个月:

"\d{2} (?:janv.|févr.|mars|avr.|mai|juin|juil.|août|sept.|oct.|nov.|déc.) \d{4}" 

嗯,这是我曾经尝试过法国月份的缩写的第一次,我可能需要做一些清理工作:

date_expr = r"\d{2} (?:%s) \d{4}" % '|'.join(
    m.title().rstrip('.') for m in calendar.month_abbr[1:]) 

现在,我得到:

"\d{2} (?:Janv|Févr|Mars|Avr|Mai|Juin|Juil|Août|Sept|Oct|Nov|Déc) \d{4}" 

而现在我的脚本也会为我的高卢朋友跑,真的很麻烦。(您可能想知道为什么我必须从[1:]开始切分month_abbr列表 - 此列表以位置0处的空字符串开头,因此如果您使用find()查找特定的月份缩写,那么您将1-12得到一个号码,而不是从0-11)

- 保罗

+0

这就是为什么我更愿意使用RE来验证基本格式(_day month-abbrev year_),然后让'strptime'负责本月的本地化。如果你真的感兴趣,你可以使用一些locale-aware选项来解决M-D-Y排序的差异。 – 2010-05-06 14:44:48

0

或者你可以用这个completelly

date = re.findall(r'\d\d\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s\d{4}\s\d{2}:\d{2}', text) 
print date 
['30 November 2010 14:20', '30 November 2010 14:24']