我想用preg_match_all解析电子邮件地址列表(如to标头中的那个),以获取用户名(如果存在)和电子邮件。类似于来自Pear的mailparse_rfc822_parse_addresses或Mail_RFC822::parseAddressList(),但在纯PHP中。
输入:
"DOE, John '(ACME')" <john.doe@somewhere.com>, "DOE, Jane" <jane.doe@somewhere.com>
输出:array(
array(
'name' => 'DOE, John (ACME)',
'email' => 'john.doe@somewhere.com'
),
array(
'name' => 'DOE, Jane',
'email' => 'jane.doe@somewhere.com'
)
)
不需要支持奇怪的电子邮件格式(/[a - z0 - 9. - _ %] + @ (- z0 - 9.) +。[a-z]{2,4}/i for email part is OK
我不能用explosion,因为逗号会出现在名字里。str_getcsv不起作用,因为我可以有:
DOE, John '(ACME') <john.doe@somewhere.com>
作为输入。
更新:
目前,我有这个:
public static function parseAddressList($addressList)
{
$pattern = '/^(?:"?([^<"]+)"?'s)?<?([^>]+@[^>]+)>?$/';
if (preg_match($pattern, $addressList, $matches)) {
return array(
array(
'name' => stripcslashes($matches[1]),
'email' => $matches[2]
)
);
} else {
$parts = str_getcsv($addressList);
$result = array();
foreach($parts as $part) {
if (preg_match($pattern, $part, $matches)) {
$result[] = array(
'name' => stripcslashes($matches[1]),
'email' => $matches[2]
);
}
}
return $result;
}
}
但是它失败了:
"DOE, '"John'"" <john.doe@somewhere.com>
我需要测试反向引用'",但我不记得如何做到这一点。
我终于做到了:
public static function parseAddressList($addressList)
{
$pattern = '/^(?:"?((?:[^"'''']|''''.)+)"?'s)?<?([a-z0-9._%-]+@[a-z0-9.-]+''.[a-z]{2,4})>?$/i';
if (($addressList[0] != '<') and preg_match($pattern, $addressList, $matches)) {
return array(
array(
'name' => stripcslashes($matches[1]),
'email' => $matches[2]
)
);
} else {
$parts = str_getcsv($addressList);
$result = array();
foreach($parts as $part) {
if (preg_match($pattern, $part, $matches)) {
$item = array();
if ($matches[1] != '') $item['name'] = stripcslashes($matches[1]);
$item['email'] = $matches[2];
$result[] = $item;
}
}
return $result;
}
}
我不知道RFC,但如果格式总是如您所示,那么您可以尝试如下:
preg_match_all("/'"([^'"]*)'"''s+<([^<>]*)>/", $string, $matches);
print_r($matches);