views:

85

answers:

3

Given a list of emails, formated:

  "FirstName Last" <[email protected]>, "NewFirst NewLast" <[email protected]>

How can I build this into a string array of Only email addresses (I don't need the names).

+1  A: 
<?php

 $s = "\"FirstName Last\" <[email protected]>, \"NewFirst NewLast\" <[email protected]>";

 $emails = array();
 foreach (split(",", $s) as $full)
 {
  preg_match("/.*<([^>]+)/", $full, $email);
  $emails[] = $email[1];
 }

 print_r($emails);
?>
John Allen
What if the quoted display name contains a comma?
Gumbo
Won't work so good
John Allen
+2  A: 

You could use preg_match_all (docs):

preg_match_all('/<([^>]+)>/', $s, $matches);
print_r($matches); // inspect the resulting array

Provided that all addresses are enclosed in < ... > there is no need to explode() the string $s.


EDIT In response to comments, the regex could be rewritten as '/<([^@]+@[^>]+)>/'. Not sure whether this is fail-safe, though :)


EDIT #2 Use a parser for any non-trivial data (see the comments below - email address parsing is a bitch). Some errors could, however, be prevented by removing duplicate addresses.

jensgram
And, of course, this fails on e-mail addresses like `">"@example.com`. Isn't e-mail great? Not that this expression wouldn't work for every e-mail in practice, *in theory* it's wrong. +1 anyway.
Welbog
What if the quoted display name contains `<…>`?
Gumbo
Your failsafe still fails in theory: `"@>"@example.com` E-mail sucks. Still, I'm liking the effort you're putting into this. You can't really parse e-mail perfectly with a regular expression. At least not a very simple one. I believe there's one floating around that's several hundred characters that does the job. http://www.ex-parrot.com/pdw/Mail-RFC822-Address.html Turns out it's several *thousand* characters.
Welbog
Now `"<[email protected]>" <[email protected]>` will result in two addresses.
Gumbo
@Gumbo In that case (i.e. name can contain `< ... @ ...>`) you should use a parser :)
jensgram
+3  A: 

PHP’s Mailparse extension has a mailparse_rfc822_parse_addresses function you might want to try. Otherwise you should build your own address parser.

Gumbo
+1 Reinventing the wheel = bad. Reinventing the wheel using regex = worse.
Ben James
+1 I got carried away with the regex approach. This seems to be *the* way to do it.
jensgram
Or, as read in this function comments, you can use this PEAR package : http://pear.php.net/manual/en/package.mail.mail-rfc822.parseaddresslist.php
Arkh