【问题标题】:Regex to extract date and time from email text正则表达式从电子邮件文本中提取日期和时间
【发布时间】:2018-08-11 19:55:13
【问题描述】:

我有一个包含大量文本的文件。其中一些看起来像这样:

X-DSPAM-Processed: Fri Jan  4 18:10:48 2008
X-DSPAM-Confidence: 0.6178
X-DSPAM-Probability: 0.0000

Details: http://source.sakaiproject.org/viewsvn/?view=rev&rev=39771

Author: louis@media.berkeley.edu
Date: 2008-01-04 18:08:50 -0500 (Fri, 04 Jan 2008)
New Revision: 39771

Modified:
bspace/site-manage/sakai_2-4-x/site-manage-tool/tool/src/bundle/sitesetupgeneric.properties
bspace/site-manage/sakai_2-4-x/site-manage-tool/tool/src/java/org/sakaiproject/site/tool/SiteAction.java
Log:
BSP-1415 New (Guest) user Notification

我只需要提取遵循此模式的日期:

2008-01-04 18:08:50 -0500

这是我尝试过的:

import re

text = open('mbox-short.txt')
for line in text:
    dates = re.compile('\d{4}(?P<sep>[-/])\d{2}(?P=sep)\d{2}\s\d{2}:\d{2}:]\d{2}\s[-/]\d{4}')
    print(dates)

text.close()

我得到的回报是几百:

\d{4}(?P<sep>[-/])\d{2}(?P=sep)\d{2}\s\d{2}:\d{2}:]\d{2}\s[-/]\d{4}

【问题讨论】:

  • re.compile 只编译模式,搜索使用 dates.search(line)
  • 这似乎不起作用,或者我不确定要替换什么。我是编程的初学者,在他们不教的地方上 Python 课,他们只是让我们“做”。我需要输出只是列表中的日期字符串。
  • @ArchivistG。所有这些日期是否都出现在以“日期:”开头的行上?因为如果他们这样做了,根本就不需要使用正则表达式:简单的字符串操作就足够了。
  • @ArchivistG。事实上,更好的解决方案是使用mailbox 模块,它可以解析mbox 文件。没有必要重新发明轮子。

标签: python regex


【解决方案1】:

两件事:

首先,正则表达式本身:

regex = re.compile(r'\b\d{4}[-/]\d{2}[-/]\d{2}\s\d{2}:\d{2}:\d{2}\s[-+]\d{4}\b')

其次,你需要调用regex.findall(file),其中file是一个字符串:

>>> regex.findall(file)
['2008-01-04 18:08:50 -0500']

re.compile() produces a compiled regular expression objectfindall 是该对象的几个方法之一,可让您进行实际的搜索/匹配/查找。

最后:您当前正在使用命名捕获组。 ((?P&lt;sep&gt;[-/])) 从您的问题中,“我只需要提取遵循此模式的日期”,您似乎不需要这些。您想提取整个表达式,而不是捕获“分隔符”,这是捕获组的设计目的。

完整代码块:

>>> import re
>>> regex = re.compile(r'\b\d{4}[-/]\d{2}[-/]\d{2}\s\d{2}:\d{2}:\d{2}\s[-+]\d{4}\b')
>>> with open('mbox-short.txt') as f:
...     print(regex.findall(f.read()))
...     
['2008-01-04 18:08:50 -0500']

【讨论】:

  • 完成。在不问另一个正式问题的情况下,我如何打印结果,同时将结果存储到列表中以备后用?
  • 当然——如果你只想存储它以在同一个 Python 会话中使用,只需使用my_variable = regex.findall(f.read()),因为findall() 返回一个列表。要使其在另一个会话中访问,请查看pickle module
  • 在时区之前允许使用减号或 斜杠 几乎肯定是错误的。您想允许加号或减号; [-+]。我意识到你只是从 OP 的代码中复制了这个,但由于这是现在公认的答案,它也应该更正这个错误。
  • RFC5322 定义了Date: 标头格式和更多标准标头。
【解决方案2】:

这是另一个解决方案。

import re
numberExtractRegex = re.compile(r'(\d\d\d\d[-]\d\d[-]\d\d\s\d\d[:]\d\d[:]\d\d\s[-]\d\d\d\d)')
print(numberExtractRegex.findall('Date: 2008-01-04 18:08:50 -0500 (Fri, 04 Jan 2008), Date: 2010-01-04 18:08:50 -0500 (Fri, 04 Jan 2010)'))

【讨论】:

  • 单一的部分本身不值得投反对票,但这个正则表达式只允许时区中的负 UTC 偏移量。在不必要的地方使用字符类也应该阻止任何人相信它会做它应该做的事情。
猜你喜欢
  • 2017-09-20
  • 2014-12-04
  • 1970-01-01
  • 2021-01-17
  • 1970-01-01
  • 2011-01-16
  • 1970-01-01
  • 2017-07-13
  • 2017-09-25
相关资源
最近更新 更多