2013-05-22 2 views
3

Там, кажется, много форматов приемлемы адресов электронной почты в поле Кому: и С: сырыми заголовками электронной почты ...Разделить полные адреса электронной почты на имя и адрес электронной почты?

[email protected] 
person <[email protected]> 
person 
Another Person <[email protected]> 
'Another Person' <[email protected]> 
"Another Person" <[email protected]> 

После не найти какие-либо эффективные 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(
    '[email protected]', 
    'monarch <[email protected]>', 
    'blahblah', 
    "'doc venture' <[email protected]>" 
    ); 

foreach ($tests as $test){ 
    echo print_r(email_split($test), true); 
} 

Я пропускаю здесь что-нибудь? Может ли кто-нибудь порекомендовать лучший способ?

ответ

3

мне удалось сделать одно регулярное выражение для ваших тестов:

[email protected] 
person <[email protected]> 
person 
Another Person <[email protected]> 
'Another Person' <[email protected]> 
"Another Person" <[email protected]> 

использование 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(
    '[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>"; 
} 

Выход я получил:

Array 
(
    [name] => 
    [email] => [email protected] 
) 

Array 
(
    [name] => monarch 
    [email] => [email protected] 
) 

Array 
(
    [name] => blahblah 
    [email] => 
) 

Array 
(
    [name] => 'doc venture' 
    [email] => [email protected] 
) 
+0

Это выглядит потрясающе! Я пробовал его на кодовом коде ... http://codepad.org/TZUBdGjQ .. но я получаю сообщение об ошибке «Неизвестный модификатор« g ». Предложения? – neokio

+0

Я пробовал это в своей тестовой среде (версия PHP 5.4.3) для кода, который я использовал и выводил, я получил -> проверить редактирование. –

+0

отличное решение! – neokio

0

использование preg_match в PHP, http://php.net/manual/en/function.preg-match.php

или по-моему, вы можете сделать свою собственную функцию (скажем get_email_address), это поймать @ характер, а затем получить «покоя левую строку» от @ до '<' символ и 'rest-right-string' от @ до символа '>'.

например, строка monarch <[email protected]> будет возвращать 'rest-left-string' = themonarch и 'rest-right-string' = tgoci.com. наконец, ваша функция get_email_address вернется [email protected]

, надеюсь, это поможет .. :)

+0

Существует достаточное количество условий и исключений, из-за которых ни один «preg_match» не выполняет трюк :(Можете ли вы представить рабочее выражение для задания, которое включает проверку? – neokio

+0

Да, я вижу, я могу представить это после просмотра содержимого вашей переменной $ tests: D. Как насчет моего второго мнения выше? – kangmasjuqi

+0

это не о разделении 'john @ doe.com' на' john' и 'doe.com' ... это об извлечении полного имени и полного адрес электронной почты от заголовков. – neokio

0

Как об этом:

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 (для моих целей) не требуется. Но в интересах ответа на ОП я добавил if, чтобы получить ожидаемые результаты OP. Это можно было бы сделать другими способами (проверьте последний элемент $ parts для '@').

Смежные вопросы