Некоторые из предыдущих ответов неверны, поскольку действительный адрес электронной почты может фактически включать в себя более одного символа @, заключая его в заключенный в кавычки текст. Смотрите следующий пример:
$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);
}