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+))
详情
(?:,\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
)
)
我有一些旧的遗留数据,其中包含字符串形式的电子邮件地址,如下所示:
$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+))
详情
(?:,\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
)
)