解析 TO 标头中符合 RFC 822 的地址 [英] Parse RFC 822 compliant addresses in a TO header

查看:47
本文介绍了解析 TO 标头中符合 RFC 822 的地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用 preg_match_all 解析电子邮件地址列表(如 TO 标头中的列表)以获取用户名(如果存在)和电子邮件.类似于来自 Pear 的 mailparse_rfc822_parse_addresses 或 Mail_RFC822::parseAddressList(),但使用纯 PHP.

I would like to parse an email address list (like the one in a TO header) with preg_match_all to get the user name (if exists) and the E-mail. Something similar to mailparse_rfc822_parse_addresses or Mail_RFC822::parseAddressList() from Pear, but in plain 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'
    )
)

不需要支持奇怪的E-mail格式(/[a-z0-9._%-]+@[a-z0-9.-]+.[az]{2,4}/i对于电子邮件部分是可以的).

Don't need to support strange E-mail format (/[a-z0-9._%-]+@[a-z0-9.-]+.[a-z]{2,4}/i for email part is OK).

我不能使用explode,因为逗号可以出现在名称中.str_getcsv 不起作用,因为我可以:

I can't use explode because the comma can appear in the name. str_getcsv doesn't work, because I can have:

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>

我需要在反向引用 \" 时进行测试,但我不记得该怎么做.

I need to test on back reference the \" but I don't remember how to do this.

推荐答案

我终于做到了:

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;
    }
}

但我不确定它是否适用于所有情况.

But I'm not sure it works for all cases.

这篇关于解析 TO 标头中符合 RFC 822 的地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆