PHP有时会在名称中拆分电子邮件字符串和逗号

时间:2017-10-25 10:39:23

标签: php string email preg-match names

我有一些旧的遗留数据,其中包含字符串中的电子邮件地址,如下所示:

$str = 'Joe Bloggs <joe@bloggs.co.uk>, Person, Test [test@person.com], me@email.com'

我想将此字符串拆分为其中包含的3封电子邮件,但您可以看到其中一些名称中包含逗号分隔符,并且某些电子邮件在开头时没有RFC规范名称。理想情况下,上面的字符串将拆分为以下数组:

Array (
    [0] => Array(
        'name' => 'Joe Blogs',
        'email' => 'joe@bloggs.co.uk'
    )
    [1] => Array(
        'name' => 'Person, Test',
        'email' => 'test@person.com'
    ),
    [2] => Array(
        'name' => '',
        'email' => 'me@email.com'
    )
)

我猜这个正则表达式会在这里工作吗?我已经提出以下内容,但它只处理一个电子邮件地址,而不是逗号分隔列表(名称中也使用逗号!):

preg_match_all('!(.*?)\s?[<|\[]\s*(.*?)\s*[>|\]]!',$string,$matches);

谢谢!

1 个答案:

答案 0 :(得分:2)

您可以使用

(?:,\s*)?(.*?)\s*(?|<([^>]*)>|\[([^][]*)]|(\S+@\S+))

请参阅regex demo

<强>详情

  • (?:,\s*)? - ,的可选序列,然后是0 +空格
  • (.*?) - 第1组(名称):除了换行符之外的任何0 +字符尽可能少
  • \s* - 0+ whitespaces
  • (?|<([^>]*)>|\[([^][]*)]|(\S+@\S+)) - 分支重置组匹配
    • <([^>]*)>| - <,然后在第1组中捕获除>以外的任何0 +字符,而>只是匹配
    • \[([^][]*)]| - [,然后在第1组中捕获除]以外的任何0 +字符,而]只是匹配
    • (\S+@\S+) - 在第1组中捕获了1个或多个非空格字符@,以及1个以上的非空白字符。

然后使用the following PHP code获取必要的结果:

$re = '/(?:,\s*)?(.*?)\s*(?|<([^>]*)>|\[([^][]*)]|(\S+@\S+))/';
$str = 'Joe Bloggs <joe@bloggs.co.uk>, Person, Test [test@person.com], me@email.com';
preg_match_all($re, $str, $m, PREG_SET_ORDER, 0);
$res = array();
foreach ($m as $e)
{   
    $res[] = array('name' => $e[1], 'address' => $e[2]);
}
print_r($res);

输出:

Array
(
    [0] => Array
        (
            [name] => Joe Bloggs
            [address] => joe@bloggs.co.uk
        )

    [1] => Array
        (
            [name] => Person, Test
            [address] => test@person.com
        )

    [2] => Array
        (
            [name] => 
            [address] => me@email.com
        )

)