Как проверить адрес электронной почты с помощью регулярного выражения? - PullRequest
3109 голосов
/ 14 октября 2008

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

Я использую его в нескольких программах PHP, и он работает большую часть времени. Однако время от времени со мной связывается кто-то, у кого проблемы с сайтом, который его использует, и мне приходится вносить некоторые коррективы (совсем недавно я понял, что не разрешаю 4-символьные TLD).

Какое лучшее регулярное выражение вы видели или видели для проверки писем?

Я видел несколько решений, в которых используются функции, использующие несколько более коротких выражений, но я бы предпочел иметь одно длинное комплексное выражение в простой функции вместо нескольких коротких выражений в более сложной функции.

Ответы [ 72 ]

4 голосов
/ 18 января 2013

Я все еще использую:

^[A-Za-z0-9._+\-\']+@[A-Za-z0-9.\-]+\.[A-Za-z]{2,}$

Но с появлением IPv6 и Unicode, возможно:

^\w[^@\s]*@[^@\s]{2,}$

лучше. Gmail уже разрешает последовательные точки, но Microsoft Exchange Server 2007 отказывается от них.

4 голосов
/ 27 марта 2014

В настоящее время существует гораздо больше (1000) ДВУ. Большинство ответов здесь нужно отклонить, поскольку они больше не верны - потенциально этот вопрос должен иметь второе издание.

Не стесняйтесь посетить более актуальную дискуссию на другой пост ... .

4 голосов
/ 31 декабря 2012

КАК в моем понимании наиболее вероятным будет охватывать ..

/^([a-z0-9_-]+)(@[a-z0-9-]+)(\.[a-z]+|\.[a-z]+\.[a-z]+)?$/is
4 голосов
/ 16 июля 2015

Для PHP я использую валидатор адреса электронной почты от Nette Framework - http://api.nette.org/2.3.3/source-Utils.Validators.php.html#234-247

/* public static */ function isEmail($value)
{
    $atom = "[-a-z0-9!#$%&'*+/=?^_`{|}~]"; // RFC 5322 unquoted characters in local-part
    $localPart = "(?:\"(?:[ !\\x23-\\x5B\\x5D-\\x7E]*|\\\\[ -~])+\"|$atom+(?:\\.$atom+)*)"; // quoted or unquoted
    $alpha = "a-z\x80-\xFF"; // superset of IDN
    $domain = "[0-9$alpha](?:[-0-9$alpha]{0,61}[0-9$alpha])?"; // RFC 1034 one domain component
    $topDomain = "[$alpha](?:[-0-9$alpha]{0,17}[$alpha])?";
    return (bool) preg_match("(^$localPart@(?:$domain\\.)+$topDomain\\z)i", $value);
}
4 голосов
/ 13 декабря 2016

Для меня правильный способ проверки электронной почты:

  1. Убедитесь, что символ @ существует, и до и после него есть не-@ символы: /^[^@]+@[^@]+$/
  2. Попробуйте отправить электронное письмо на этот адрес с некоторым «кодом активации».
  3. Когда пользователь «активирует» свой адрес электронной почты, мы увидим, что все в порядке.

Конечно, вы можете показывать некоторые предупреждения или всплывающую подсказку во внешнем интерфейсе, когда пользователь вводит «странное» электронное письмо, чтобы помочь ему избежать распространенных ошибок, таких как отсутствие точки в доменной части или пробелов в имени без цитирования и т. Но вы должны принять адрес "hello @ world", если пользователь действительно этого хочет.

Кроме того, вы должны помнить, что стандартный адрес электронной почты был и может эволюционировать, поэтому вы не можете просто ввести какое-то «стандартно-действительное» регулярное выражение раз и навсегда. И вы должны помнить, что некоторые конкретные интернет-серверы могут не работать с некоторыми деталями общего стандарта и фактически работать с собственным «измененным стандартом».

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

3 голосов
/ 14 января 2013

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

[\w+-]+(?:\.[\w+-]+)*@[\w+-]+(?:\.[\w+-]+)*(?:\.[a-zA-Z]{2,4})

Я думаю, что есть объяснение, поэтому вы можете изменить его, если хотите:

( e ) [\w+-]+ соответствует a-z, A-Z, _, +, - хотя бы один раз

( m ) (?:\.[\w+-]+)* соответствует a-z, A-Z, _, +, - ноль или более раз, но начинать нужно с a. (точка)

@ = @

( i ) [\w+-]+ соответствует a-z, A-Z, _, +, - хотя бы один раз

( l ) (?:\.[\w+-]+)* соответствует a-z, A-Z, _, +, - ноль или более раз, но начинать нужно с a. (точка)

( com ) (?:\.[a-zA-Z]{2,4}) соответствует a-z, A-Z от 2 до 4 раз, начиная с a. (Точка)

дает e(.m)@i(.l).com, где (.m) и (.l) являются необязательными, но также могут повторяться несколько раз. Я думаю, что это проверяет все действительные адреса электронной почты, но блокирует потенциально недействительные без использования слишком сложного регулярного выражения, которое в большинстве случаев не понадобится.

обратите внимание, что это позволит +@-.com, но это компромисс для простоты.

3 голосов
/ 28 декабря 2016

Элемент списка

Я использую эту функцию

function checkmail($value){
        $value = trim($value);
        if( stristr($value,"@") 
            && stristr($value,".") 
            && (strrpos($value, ".") - stripos($value, "@") > 2) 
            && (stripos($value, "@") > 1) 
            && (strlen($value) - strrpos($value, ".") < 6) 
            && (strlen($value) - strrpos($value, ".") > 2) 
            && ($value == preg_replace('/[ ]/', '', $value)) 
            && ($value == preg_replace('/[^A-Za-z0-9\-_.@!*]/', '', $value))
        ){

        }else{
            return "Invalid Mail-Id";
        }
    }
3 голосов
/ 05 августа 2011

Это правило соответствует тому, что наш постфиксный сервер не мог отправить.

разрешить буквы, цифры, -, _, +,., &, /,!

нет -foo@bar.com

нет asd@-bar.com

/^([a-z0-9\+\._\/&!][-a-z0-9\+\._\/&!]*)@(([a-z0-9][-a-z0-9]*\.)([-a-z0-9]+\.)*[a-z]{2,})$/i
3 голосов
/ 04 ноября 2011

Я бы не советовал использовать регулярные выражения - адреса электронной почты слишком сложны для этого. Это распространенная проблема, поэтому я думаю, что есть много библиотек, которые содержат валидатор - если вы используете Java, EmailValidator из apache commons validator - хорошая.

3 голосов
/ 31 июля 2014

Пришлось упомянуть, что чуть ли не был добавлен новый домен «яндекс». Возможные электронные письма: test@job.yandex. А также поддерживаются прописные буквы, поэтому немного измененная версия решения acrosman:

^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*(\.[a-zA-Z]{2,6})$
...