There seems to be many acceptable email address formats in the To: and From: raw email headers ...
[email protected]
person <[email protected]>
person
Another Person <[email protected]>
'Another Person' <[email protected]>
"Another Person" <[email protected]>
After not finding any effective PHP functions for splitting out names and addresses, I've written the following code.
You can DEMO IT ON CODEPAD to see the output...
// validate email address
function validate_email( $email ){
return (filter_var($email, FILTER_VALIDATE_EMAIL)) ? true : false;
}
// split email into name / address
function email_split( $str ){
$name = $email = '';
if (substr($str,0,1)=='<') {
// first character = <
$email = str_replace( array('<','>'), '', $str );
} else if (strpos($str,' <') !== false) {
// possibly = name <email>
list($name,$email) = explode(' <',$str);
$email = str_replace('>','',$email);
if (!validate_email($email)) $email = '';
$name = str_replace(array('"',"'"),'',$name);
} else if (validate_email($str)) {
// just the email
$email = $str;
} else {
// unknown
$name = $str;
}
return array( 'name'=>trim($name), 'email'=>trim($email) );
}
// test it
$tests = array(
'[email protected]',
'monarch <[email protected]>',
'blahblah',
"'doc venture' <[email protected]>"
);
foreach ($tests as $test){
echo print_r( email_split($test), true );
}
Am I missing anything here? Can anyone recommend a better way?
I have managed to make one regex to your test cases:
[email protected]
person <[email protected]>
person
Another Person <[email protected]>
'Another Person' <[email protected]>
"Another Person" <[email protected]>
using preg_match
with this regex will surely help you bit.
function email_split( $str ){
$sPattern = "/([\w\s\'\"]+[\s]+)?(<)?(([\w-\.]+)@((?:[\w]+\.)+)([a-zA-Z]{2,4}))?(>)?/g";
preg_match($sPattern,$str,$aMatch);
if(isset($aMatch[1]))
{
echo $aMatch[1] //this is name;
}
if(isset($aMatch[3]))
{
echo $aMatch[3] //this is EmailAddress;
}
}
Note: I just noticed that single "person" i.e. your third test case could be discarded with this regex (just that because of space constraint in regex) so,at first line of your email_split
function, append space at last place of your string.
Then it would be bang on target.
Thanks, Hope this helps.
Code I tried:
<?php
// validate email address
function validate_email($email) {
return (filter_var($email, FILTER_VALIDATE_EMAIL)) ? true : false;
}
// split email into name / address
function email_split($str) {
$str .=" ";
$sPattern = '/([\w\s\'\"]+[\s]+)?(<)?(([\w-\.]+)@((?:[\w]+\.)+)([a-zA-Z]{2,4}))?(>)?/';
preg_match($sPattern, $str, $aMatch);
//echo "string";
//print_r($aMatch);
$name = (isset($aMatch[1])) ? $aMatch[1] : '';
$email = (isset($aMatch[3])) ? $aMatch[3] : '';
return array('name' => trim($name), 'email' => trim($email));
}
// test it
$tests = array(
'[email protected]',
'monarch <[email protected]>',
'blahblah',
"'doc venture' <[email protected]>"
);
foreach ($tests as $test) {
echo "<pre>";
echo print_r(email_split($test), true);
echo "</pre>";
}
Output I got:
Array
(
[name] =>
[email] => [email protected]
)
Array
(
[name] => monarch
[email] => [email protected]
)
Array
(
[name] => blahblah
[email] =>
)
Array
(
[name] => 'doc venture'
[email] => [email protected]
)