Разделенный адрес электронной почты Regex - PullRequest
11 голосов
/ 28 июля 2011

Мне нужна помощь с php regex, я хочу разделить адрес электронной почты "johndoe@example.com" на "johndoe" и "@ example.com"

До сих пор у меня есть это: preg_match('/<?([^<]+?)@/', 'johndoe@example.com', $matches); И я получаю Array ( [0] => johndoe@ [1] => johndoe)

Так как мне нужно изменить регулярное выражение?

Ответы [ 6 ]

26 голосов
/ 28 июля 2011
$parts = explode('@', "johndoe@example.com");

$user = $parts[0];
// Stick the @ back onto the domain since it was chopped off.
$domain = "@" . $parts[1];
7 голосов
/ 30 марта 2016

Некоторые из предыдущих ответов неверны, поскольку действительный адрес электронной почты может фактически включать в себя более одного символа @, заключая его в заключенный в кавычки текст. Смотрите следующий пример:

$email = 'a."b@c".d@e.f';
echo (filter_var($email, FILTER_VALIDATE_EMAIL) ? 'V' : 'Inv'), 'alid email format.';

Допустимый формат электронной почты.


Могут существовать несколько разделенных блоков текста и множество символов @. Оба эти примера являются действительными адресами электронной почты:

$email = 'a."b@c".d."@".e.f@g.h';
$email = '/."@@@@@@"./@a.b';

Исходя из разорванного ответа Майкла Берковски, этот адрес электронной почты будет выглядеть так:

$email = 'a."b@c".d@e.f';
$parts = explode('@', $email);
$user = $parts[0];
$domain = '@' . $parts[1];

Пользователь: a. "B"
Домен: @c ".d


Любой, кто использует это решение, должен остерегаться возможного злоупотребления. Принятие адреса электронной почты на основе этих результатов с последующей вставкой $ email в базу данных может иметь негативные последствия.

$email = 'a."b@c".d@INSERT BAD STUFF HERE';

Содержимое этих функций является точным только при условии, что filter_var сначала используется для проверки.

Слева:

Вот простое не-регулярное, неразрывное решение для поиска первого @, который не содержится в тексте с разделителями и кавычками. Вложенный текст с разделителями считается недопустимым на основании filter_var, поэтому поиск правильного @ - это очень простой поиск.

if(filter_var($email, FILTER_VALIDATE_EMAIL)) {
    $a = '"';
    $b = '.';
    $c = '@';
    $d = strlen($email);
    $contained = false;
    for($i = 0; $i < $d; ++$i) {
        if($contained) {
            if($email[$i] === $a && $email[$i + 1] === $b) {
                $contained = false;
                ++$i;
            }
        }
        elseif($email[$i] === $c)
            break;
        elseif($email[$i] === $b && $email[$i + 1] === $a) {
            $contained = true;
            ++$i;
        }
    }
    $local = substr($email, 0, $i);
    $domain = substr($email, $i);
}

Вот тот же код, скрытый внутри функции.

function parse_email($email) {
    if(!filter_var($email, FILTER_VALIDATE_EMAIL)) return false;
    $a = '"';
    $b = '.';
    $c = '@';
    $d = strlen($email);
    $contained = false;
    for($i = 0; $i < $d; ++$i) {
        if($contained) {
            if($email[$i] === $a && $email[$i + 1] === $b) {
                $contained = false;
                ++$i;
            }
        }
        elseif($email[$i] === $c)
            break;
        elseif($email[$i] === $b && $email[$i + 1] === $a) {
            $contained = true;
            ++$i;
        }
    }
    return array('local' => substr($email, 0, $i), 'domain' => substr($email, $i));
}

Используется:

$email = 'a."b@c".x."@".d.e@f.g';
$email = parse_email($email);
if($email !== false)
    print_r($email);
else
    echo 'Bad email address.';

Array ([local] => a. "B @ c" .x. "@". D.e [domain] => @ f.g)

$email = 'a."b@c".x."@".d.e@f.g@';
$email = parse_email($email);
if($email !== false)
    print_r($email);
else
    echo 'Bad email address.';

Неверный адрес электронной почты.


Справа:

После некоторого тестирования filter_var и исследования того, что допустимо в качестве допустимого доменного имени ( Имена хостов , разделенные точками), я создал эту функцию для повышения производительности. В действительном адресе электронной почты последний @ должен быть истинным @, поскольку символ @ никогда не должен появляться в домене действительного адреса электронной почты.

if(filter_var($email, FILTER_VALIDATE_EMAIL)) {
    $domain = strrpos($email, '@');
    $local = substr($email, 0, $domain);
    $domain = substr($email, $domain);
}

Как функция:

function parse_email($email) {
    if(!filter_var($email, FILTER_VALIDATE_EMAIL)) return false;
    $a = strrpos($email, '@');
    return array('local' => substr($email, 0, $a), 'domain' => substr($email, $a));
}

Или с помощью взрыва и взрыва:

if(filter_var($email, FILTER_VALIDATE_EMAIL)) {
    $local = explode('@', $email);
    $domain = '@' . array_pop($local);
    $local = implode('@', $local);
}

Как функция:

function parse_email($email) {
    if(!filter_var($email, FILTER_VALIDATE_EMAIL)) return false;
    $email = explode('@', $email);
    $domain = '@' . array_pop($email);
    return array('local' => implode('@', $email), 'domain' => $domain);
}
3 голосов
/ 28 июля 2011

Использование explode, вероятно, является лучшим подходом здесь, но чтобы сделать это с регулярным выражением, вы должны сделать что-то вроде этого:

/^([^@]*)(@.*)/

^ начало строки

([^ @] *) все, что не является символом @ ($ соответствует [0])

(@. *) @, за которым следует что-либо ($ матчей [1])

1 голос
/ 15 июня 2016

Ответ

$parts = explode("@", $email);
$domain = array_pop($parts);
$name = implode("@",$parts);

Это решает оба крайних случая Брогана (a."b@c".d."@".e.f@g.h и /."@@@@@@"./@a.b), как вы можете видеть в этом Ideone


в настоящее время принятый ответ недопустим из-за множественного случая "@".

Мне нравился @ ответ Брогана , пока я не прочитал его последнее предложение:

В действительном адресе электронной почты последний @ должен быть истинным @, поскольку символ @ никогда не должен появляться в домене действительного адреса электронной почты.

Это поддерживается этот другой ответ .И если это правда, его ответ кажется излишне сложным.

0 голосов
/ 25 января 2017

Используйте регулярное выражение. Например:

$mailadress = "email@company.com";     
$exp_arr= preg_match_all("/(.*)@(.*)\.(.*)/",$mailadress,$newarr, PREG_SET_ORDER); 

/*
Array output:
Array
(
    [0] => Array
        (
            [0] => email@company.com
            [1] => email
            [2] => company
            [3] => com
        )

)
*/
0 голосов
/ 28 июля 2011

Если вы хотите решение preg_match, вы также можете сделать что-то вроде этого

preg_match('/([^<]+)(@[^<]+)/','johndoe@example.com',$matches);
...