regex 用PHP解析电子邮件地址?,

c9qzyr3d  于 2023-01-03  发布在  PHP
关注(0)|答案(6)|浏览(205)

this question类似,如何解析这种格式的电子邮件地址,

"Bob Smith" <bob@company.com>, joe@company.com, "John Doe"<john@company.com>

得到这样的结果:

array(
    'bob@company.com'=>'Bob Smith'
    'joe@company.com'=>''
    'john@company.com'=>'John Doe'
);
pbgvytdp

pbgvytdp1#

那么,你可以使用mailparse_rfc822_parse_addresses(),它就是这样做的,它是一个PECL扩展,所以使用评论中提到的Mail_RFC822::parseAddressList()可能会更容易。

zf2sa74q

zf2sa74q2#

这应该适用于几乎任何情况:

$str = '"Bob Smith" <bob@company.com>, joe@company.com, "John Doe"<john@company.com>, Billy Doe<billy@company.com>';
$emails = array();

if(preg_match_all('/\s*"?([^><,"]+)"?\s*((?:<[^><,]+>)?)\s*/', $str, $matches, PREG_SET_ORDER) > 0)
{
    foreach($matches as $m)
    {
        if(! empty($m[2]))
        {
            $emails[trim($m[2], '<>')] = $m[1];
        }
        else
        {
            $emails[$m[1]] = '';
        }
    }
}

print_r($emails);

结果:

Array
(
    [bob@company.com] => Bob Smith
    [joe@company.com] => 
    [john@company.com] => John Doe
    [billy@company.com] => Billy Doe
)
ny6fqffe

ny6fqffe3#

下面是一段完整的代码,它甚至可以验证电子邮件是否正确;)

<?php
$mails = '"Bob Smith" <bob@company.com>, joe@company.com, "John Doe"<john@company.com>';

$records = explode(",",$mails);

foreach($records as $r){
  preg_match("#\"([\w\s]+)\"#",$r,$matches_1);
  $name = $matches_1[1];

  preg_match("/[^0-9<][A-z0-9_]+([.][A-z0-9_]+)*[@][A-z0-9_]+([.][A-z0-9_]+)*[.][A-z]{2,4}/i",$r,$matches_2);
  $email = $matches_2[0];

  echo "Name: $name <br /> Email: $email <br />";
}

?>
lo8azlld

lo8azlld4#

对于类似的任务,我使用了以下正则表达式:

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

https://regex101.com/r/Lpsjmr/1
PHP代码:

$str = '"Bob Smith" <bob@company.com>, joe@company.com, "John Doe"<john@company.com>, Billy Doe<billy@company.com>';
if (preg_match_all('/\s*(?:"([^"]*)"|([^,""<>]*))?\s*(?:(?:,|<|\s+|^)([^<@\s,]+@[^>@\s,]+)>?)\s*/', $str, $matches, PREG_SET_ORDER) > 0) {
    $matches = array_map(function($x) { return [$x[1] . $x[2], $x[3]]; }, $matches);
    print_r($matches);
}
eit6fx6z

eit6fx6z5#

1.用逗号分隔字符串
1.如果电子邮件有效,则存储它,如果否
1.删除“〉”字符
1.按“〈”分解
1.修剪('"'和' ')的字符串

8xiog9wr

8xiog9wr6#

对于@mario's answer中的原生函数无法正确解析的输入字符串,请使用"branch resets"((?|...))和捕获组((...))解析分隔逗号之间的子字符串。
分支重置确保(可选地发生)名称始终存储在匹配数组的1列中,并且电子邮件始终存储在2列中。
代码:(Demo

$emails = '"Bob Smith" <bob@company.com>, joe@company.com, "John Doe"<john@company.com>, Billy Doe<billy@company.com>';

preg_match_all('/(?|(?|"([^"]+)"|([^<@]+)) ?<(.+?)>|()(.+?))(?:$|, ?)/', $emails, $matches, PREG_SET_ORDER);
var_export(
    array_column($matches, 1, 2)
);

相关问题