2010-05-05 112 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']