解析类似电子邮件的标头(类似于 RFC822)
Posted
技术标签:
【中文标题】解析类似电子邮件的标头(类似于 RFC822)【英文标题】:Parsing e-mail-like headers (similar to RFC822) 【发布时间】:2012-09-30 01:41:36 【问题描述】:问题/疑问
我想解析一个database of bot information。据说是similar to RFC822 messages。
在我重新发明***并编写自己的解析器之前,我想我会看看其他东西是否已经可用。我偶然发现了imap_rfc822_parse_headers()
,这似乎正是我想要的。不幸的是,IMAP 扩展在我的环境中不可用。
我在网上和 Stack Overflow 上看到了许多替代方案。不幸的是,它们都是为电子邮件而构建的,并且做的比我需要的要多……经常解析出整个电子邮件并以特殊方式处理标题。我只想简单地将这些标头解析为有用的对象或数组。
是否有可用的imap_rfc822_parse_headers()
的直接 php 版本,或者可以解析这样的数据的等效版本?如果没有,我会自己写。
样本数据
robot-id: abcdatos
robot-name: ABCdatos BotLink
robot-from: no
robot-useragent: ABCdatos BotLink/1.0.2 (test links)
robot-language: basic
robot-description: This robot is used to verify availability of the ABCdatos
directory entries (http://www.abcdatos.com), checking
HTTP HEAD. Robot runs twice a week. Under HTTP 5xx
error responses or unable to connect, it repeats
verification some hours later, verifiying if that was a
temporary situation.
robot-history: This robot was developed by ABCdatos team to help
working in the directory maintenance.
robot-environment: commercial
modified-date: Thu, 29 May 2003 01:00:00 GMT
modified-by: ABCdatos
robot-id: acme-spider
robot-name: Acme.Spider
robot-cover-url: http://www.acme.com/java/software/Acme.Spider.html
robot-exclusion: yes
robot-exclusion-useragent: Due to a deficiency in Java it's not currently possible to set the User-Agent.
robot-noindex: no
robot-host: *
robot-language: java
robot-description: A Java utility class for writing your own robots.
robot-history:
robot-environment:
modified-date: Wed, 04 Dec 1996 21:30:11 GMT
modified-by: Jef Poskanzer
...
【问题讨论】:
您可以在您的环境中安装mailparse 吗?它缺乏文档,但相对容易实现。 @jackflash,我刚刚检查了一下,似乎 mailparse 也不可用。无论如何,我没有看到其中的功能可以满足我的需求。感谢您的建议! 【参考方案1】:消息 MIME 类型很常见。解析器存在很多,但通常很难用谷歌搜索。如果格式有点一致,我个人在这里使用正则表达式。
例如这两个就可以了:
// matches a consecutive RFC821 style key:value list
define("RX_RFC821_BLOCK", b"/(?:^\w[\w.-]*\w:.*\R(?:^[ \t].*\R)*)++\R*/m");
// break up Key: value lines
define("RX_RFC821_SPLIT", b"/^(\w+(?:[-.]?\w+)*)\s*:\s*(.*\n(?:^[ \t].*\n)*)/m");
第一个打破了 message/* 行的连贯块,第二个可用于拆分每个这样的块。不过,它需要后处理以从连续值线中去除前导缩进。
【讨论】:
谢谢!但是,处理缩进是我最麻烦的部分。我有一个单独的问题要表达来做那部分。你介意看看吗? ***.com/q/12805580/362536 在打破个人价值观后,我只想在这里ltrim()
。但是根据您的其他问题/\n\s(?<!\n)/
可能会折叠续行。
我无法让您的表达方式起作用,但我确实在这里找到了合适的表达方式:***.com/a/4227885/362536 现在我只需要拆分行等。我可以轻松做到这一点。【参考方案2】:
假设$data
包含您在上面粘贴的示例数据,这里是解析器:
<?php
/*
* $data = <<<'DATA'
* <put-sample-data-here>
* DATA;
*
*/
$parsed = array();
$blocks = preg_split('/\n\n/', $data);
$lines = array();
$matches = array();
foreach ($blocks as $i => $block)
$parsed[$i] = array();
$lines = preg_split('/\n(([\w.-]+)\: *((.*\n\s+.+)+|(.*(?:\n))|(.*))?)/',
$block, -1, PREG_SPLIT_DELIM_CAPTURE);
foreach ($lines as $line)
if(preg_match('/^\n?([\w.-]+)\: *((.*\n\s+.+)+|(.*(?:\n))|(.*))?$/',
$line, $matches))
$parsed[$i][$matches[1]] = preg_replace('/\n +/', ' ',
trim($matches[2]));
print_r($parsed);
【讨论】:
以上是关于解析类似电子邮件的标头(类似于 RFC822)的主要内容,如果未能解决你的问题,请参考以下文章