To:和From:原始电子邮件标题中似乎有许多可接受的电子邮件地址格式......
person@place.com
person <person@place.com>
person
Another Person <person@place.com>
'Another Person' <person@place.com>
"Another Person" <person@place.com>
在找不到任何有效的PHP函数来分割出名称和地址之后,我编写了以下代码。
您可以 DEMO IT ON CODEPAD 查看输出...
// 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(
'person@place.com',
'monarch <themonarch@tgoci.com>',
'blahblah',
"'doc venture' <doc@venture.com>"
);
foreach ($tests as $test){
echo print_r( email_split($test), true );
}
我在这里遗漏了什么?任何人都可以推荐更好的方式吗?
答案 0 :(得分:3)
我已经设法为你的测试用例制作了一个正则表达式:
person@place.com
person <person@place.com>
person
Another Person <person@place.com>
'Another Person' <person@place.com>
"Another Person" <person@place.com>
使用preg_match
这个正则表达式肯定会帮助你。
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;
}
}
注意:我刚注意到单个“人”,即你的第三个测试用例可以被这个正则表达式丢弃(只是因为正则表达式中的空间限制)所以,在你的email_split
函数的第一行,附加空格在你的字符串的最后一个地方。
然后就会瞄准目标。
谢谢,希望这有帮助。
我试过的代码:
<?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(
'person@place.com',
'monarch <themonarch@tgoci.com>',
'blahblah',
"'doc venture' <doc@venture.com>"
);
foreach ($tests as $test) {
echo "<pre>";
echo print_r(email_split($test), true);
echo "</pre>";
}
我得到的输出:
Array
(
[name] =>
[email] => person@place.com
)
Array
(
[name] => monarch
[email] => themonarch@tgoci.com
)
Array
(
[name] => blahblah
[email] =>
)
Array
(
[name] => 'doc venture'
[email] => doc@venture.com
)
答案 1 :(得分:1)
这个怎么样:
function email_split($str) {
$parts = explode(' ', trim($str));
$email = trim(array_pop($parts), "<> \t\n\r\0\x0B");
$name = trim(implode(' ', $parts), "\"\' \t\n\r\0\x0B");
if ($name == "" && strpos($email, "@") === false) { // only single string - did not contain '@'
$name = $email;
$email = "";
}
return array('name' => $name, 'email' => $email);
}
看起来这大约是正则表达式解决方案的两倍。
注意:不需要OPs第三个测试用例(出于我的目的)。但为了回答OP,我添加了if stmt以产生OP预期结果。这可以通过其他方式完成(检查'@'的$ parts的最后一个元素。)
答案 2 :(得分:0)
在php中使用preg_match,http://php.net/manual/en/function.preg-match.php
或者在我看来,你可以创建自己的功能(比如 get_email_address ),它会捕获 @ 字符,然后从中获取'rest-left-string' @ 直到'&lt;'字符和来自 @ 的'rest-right-string'直到'&gt;'字符。
例如,字符串monarch <themonarch@tgoci.com>
将返回'rest-left-string'= themonarch
和'rest-right-string'= tgoci.com
。最后,您的函数 get_email_address 将返回 themonarch@tgoci.com
希望它有所帮助.. :)
答案 3 :(得分:0)
不幸的是,正则表达式在全名的几种情况下失败:
我以此方式调整了表情
$sPattern = '/([^<]*)?(<)?(([\w-\.]+)@((?:[\w]+\.)+)([a-zA-Z]{2,4}))?(>)?/';
现在所有字符都可以正确识别和分割。
经过
测试
$address = "Test User @ `` . !! ? <test@email.com";
7年后,希望对您有所帮助:)