Reputation: 54776
Similar to this question, how could I parse e-mail addresses which are in this format,
"Bob Smith" <[email protected]>, [email protected], "John Doe"<[email protected]>
And get the a result like this:
array(
'[email protected]'=>'Bob Smith'
'[email protected]'=>''
'[email protected]'=>'John Doe'
);
Upvotes: 5
Views: 13697
Reputation: 47894
For input strings that are not properly parsed by the native function in @mario's answer, parse the substrings between delimiting commas using "branch resets" ((?|...)
) and capture groups ((...)
).
The branch reset ensure that (optionally occurring) names are always stored in column 1
of the matches array and that emails are always stored in column 2
.
Code: (Demo)
$emails = '"Bob Smith" <[email protected]>, [email protected], "John Doe"<[email protected]>, Billy Doe<[email protected]>';
preg_match_all('/(?|(?|"([^"]+)"|([^<@]+)) ?<(.+?)>|()(.+?))(?:$|, ?)/', $emails, $matches, PREG_SET_ORDER);
var_export(
array_column($matches, 1, 2)
);
Upvotes: 0
Reputation: 126
For a similar task I've used the following regex:
\s*(?:"([^"]*)"|([^,""<>]*))?\s*(?:(?:,|<|\s+|^)([^<@\s,]+@[^>@\s,]+)>?)\s*
https://regex101.com/r/Lpsjmr/1
PHP code:
$str = '"Bob Smith" <[email protected]>, [email protected], "John Doe"<[email protected]>, Billy Doe<[email protected]>';
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);
}
Upvotes: 1
Reputation: 14128
This should work with just about anything:
$str = '"Bob Smith" <[email protected]>, [email protected], "John Doe"<[email protected]>, Billy Doe<[email protected]>';
$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);
Result:
Array
(
[[email protected]] => Bob Smith
[[email protected]] =>
[[email protected]] => John Doe
[[email protected]] => Billy Doe
)
Upvotes: 8
Reputation: 5410
This is a fully working piece of code below that even validates whether the email is correct or not ;)
<?php
$mails = '"Bob Smith" <[email protected]>, [email protected], "John Doe"<[email protected]>';
$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 />";
}
?>
Upvotes: 1
Reputation: 145482
Well, you could use mailparse_rfc822_parse_addresses()
, which does exactly that. It's a PECL extension, so it might be easier to use Mail_RFC822::parseAddressList()
as mentioned in the comments.
Upvotes: 12
Reputation: 18273
Upvotes: 0