使用正则表达式解析电子邮件会话

时间:2009-11-04 07:14:25

标签: regex email

我正在编写一个需要从电子邮件会话中提取元数据的BI应用程序。 即给出一个电子邮件主题,我希望提取所有参与者和对话的结构。例如,给出这样的对话:

From: me
To: You
CC: someone

<Body>

From: You
To: Someone
CC: Someone else

<Body>

我想要提取“你”发送并通过电子邮件发送给“某人”,将“CC”转发给“SomeOneelse”,所有这些都是从“我”转发给“你”,抄送给'某人'......

我的问题是我需要处理不同的提供商。

是否有人熟悉网上某处满足此类要求的一组正则表达式?

谢谢!

3 个答案:

答案 0 :(得分:2)

我不明白你对“不同提供者”的意思。电子邮件标题符合a standard。所以你需要的正则表达式就是解析:

To: <contacts>
From: <contact>
Cc: <contacts>

更“复杂”的部分是<contact>位。有关详细规范,请查看section 3.4 of the mentioned standard

还有一些有用的regex examples for email-addresses可用。因此,采用最基本的示例,它可能看起来像这样(假设所有都是大写的):

\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b

现在,添加To:字符串:

\bTo: [A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b

从技术上讲,标题(如To:)总是从行的开头开始,所以你可以这样做:

^To: [A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b

如果您需要提取电子邮件地址,则需要添加捕获组:

^To: ([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4})\b

这只会捕获一个地址,因此您可能希望从此处扩展:

^To: ([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4})(,\s*[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4})*\b

这是一种非常天真的匹配多个地址的方法。您将最终在一个捕获组中拥有第一个地址,并在第二个组中拥有所有其余地址。更好的方法是与此相匹配。如果匹配,请删除前导To:,用逗号分割并修剪其余部分。

正如你所看到的,你在这里打开了一点虫子。解析电子邮件并不像看起来那么简单。解析标题很简单(基于上面的例子)。然而,消息体是一种不同的野兽。几乎每个电子邮件客户端(Thunderbird,Outlook(express),mutt,...)处理这个略有不同。有时新版本的行为与旧版本不同。这在很大程度上取决于客户端设置,系统区域设置等。用户是否发送UTF8,引用的可打印,CP1252,......?引用标准:

  

注意:本规范并非旨在规定网站使用的内部格式,   特定的消息系统功能,他们应该支持,或任何   创建或读取消息的用户界面程序的特征。此外,   本文档未指定传输或字符的编码   存储;也就是说,它没有指定使用的位数或这些位的方式   专门通过电线传输或存储在磁盘上。

您可能很幸运,因为发送电子邮件客户端添加了一个标头,指定了编码,但是没有强制执行此操作(AFAICS)。

下一件大事是多部分消息。这也有些不稳定。

我的建议是使用现成的库来进行解析。我确信,大多数流行语言都有一个可用的库,可以让这项任务更加轻松

答案 1 :(得分:1)

如果您希望自己实施,请点击此处:http://www.ietf.org/rfc/rfc2822.txt

答案 2 :(得分:0)

你在问不可能。这是你需要使用真正的解析器的东西,而不仅仅是用正则表达式构建东西。

你可以在这里查看答案Parse email content from quoted reply,其中有人试图用正则表达式做这样的事情并评论它是多么棘手。请阅读the paper on assembling email threads

如果你想要一些测试数据试试这个,你可以下载Enron dataset,其中包含安然人在崩溃之前发送/接收的50万封电子邮件(400meg压缩)。