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

PHP split emails string with commas in names sometimes

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

$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);

谢谢!

您可以使用

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

regex demo

详情

  • (?:,\s*)? - , 的可选序列,然后是 0+ 个空格
  • (.*?) - 第 1 组(名称):除换行字符外的任何 0+ 个字符尽可能少
  • \s* - 0+ 个空格
  • (?|<([^>]*)>|\[([^][]*)]|(\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
        )

)