我正在开发一个读取电子邮件内容的PHP脚本,并提取某些信息以存储在数据库中。
使用imap_fetchbody($ imap_stream,$ msg_number,1),我能够得到电子邮件的正文。在某些情况下(特别是从手机发送的短信电子邮件),电子邮件正文如下:
===------=_Part_110734_170079945.1283532109852
Content-Type: text/html;charset=UTF-8;
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Multimedia Message</title>
</head>
<body leftmargin="0" topmargin="0">
<tr height="15" style="border-top: 1px solid #0F7BBC;">
<td>
SMS to email test
</td>
</tr>
</body>
</html>
------=_Part_110734_170079945.1283532109852--===
我想提取电子邮件的“内容”。所以,我的计划是:
检查主体是否包含“html”标签。如果没有,我可以正常阅读(它不是HTML电子邮件)。
如果是,请在“html”标签之间提取内容。然后,删除所有其他HTML标记,“内容”就是剩下的内容。
但是,当谈到正则表达式时,我很无能为力。
我试过了:
$pattern = '/<html[^>]*>(.*?)<\/html>/i';
preg_match($pattern, $body, $matches);
// my 'content' should be in $matches[1]
但这不起作用(可能是因为$ body包含换行符和其他空格)。所以我试过这个:
$pattern = '/<html[^>]*>([.\s]*?)<\/html>/i';
preg_match($pattern, $body, $matches);
但这也不起作用。
那么,我可以使用什么$ pattern来提取“html”标签之间的所有文本?
更新:我偶然发现了一个解决方法 - 首先删除所有空格:
$body = preg_replace('/\s\s+/', ' ', $body);
$pattern = '/<body[^>]*>(.*?)<\/body>/';
我怀疑这不是最快或最有效的方法,但它有效,并且是迄今为止我所做的最好的方法。如果有的话,我仍然会欣赏更好的解决方案。
更新2:感谢Gumbo的建议,我尝试了一下,仔细研究电子邮件的结构,找到我想要的部分,而不是尝试使用正则表达式HTML。我终于找到了这个:http://docstore.mik.ua/orelly/webprog/pcook/ch17_04.htm,它解释了如何完全按照我的需要做。
答案 0 :(得分:3)
$pattern = '/<html[^>]*>([^\00]*?)<\/html>/i';
只有在内容中有0x00
个字节时才会中断,这不应该是。
答案 1 :(得分:2)
您可以使用如下的html解析器: http://php-html.sourceforge.net/
或者您可以使用strip_tags php.net/strip_tags
答案 2 :(得分:2)
[.\s]
表示文字.
或空格字符。您需要的是(.|\s)
或[\s\S]
,或者只需将s modifier设置为.
也匹配换行符。
但除此之外,you should not use regular expressions to match HTML。 HTML的一部分不是常规的,因此您不能使用正则表达式来描述它。
但除此之外,当你有明确的分隔符时,你不应该试着猜测多部分内容的范围。但这些不是<html>…</html>
。因为他们失踪怎么办?那你的尝试就会失败。使用消息本身定义的分隔符:boundary值。因此,使用边界来获取部分并在第一个CRLF + CRLF序列中将它们分开,以将标题与正文分开。
但除此之外,为什么不使用IMAP functions来获取身体?我不熟悉PHP的IMAP API,但可能有一个功能完全符合您的要求。
答案 3 :(得分:1)
您只需要添加s
modifier以允许.
匹配换行符:
$pattern = '/<html[^>]*>(.*?)<\/html>/si';
preg_match($pattern, $body, $matches);