Как проверить адрес электронной почты с помощью регулярного выражения?

2819

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

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

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

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

  • 48
    Я не хочу создавать отдельный ответ для этого, но я бы сказал, что единственный разумный способ проверить адрес электронной почты на практике - это проверить, есть ли в нем символ «@». Там просто нет причин идти дальше, чем это. Адрес может быть действительным, но не существующим, и для этого ни одно регулярное выражение не может проверить; несуществующий адрес не лучше недействительного.
  • 15
    Несколько актуально XKCD
Показать ещё 3 комментария
Теги:
validation
email
string-parsing
email-validation

77 ответов

2205
Лучший ответ

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

Одно регулярное выражение, поддерживающее RFC 5322, находится в верхней части страницы http://emailregex.com/, но использует шаблон IP-адреса, который плавает вокруг в Интернете с ошибкой, которая позволяет 00 для любого из десятичных знаков без знака в адресе с разделителями точек, что является незаконным. Остальная часть, по-видимому, согласуется с грамматикой RFC 5322 и проходит несколько тестов с использованием grep -Po, включая имена доменов, IP-адреса, плохие и имена учетных записей с кавычками и без них.

Исправление ошибки 00 в шаблоне IP, мы получаем рабочее и довольно быстрое регулярное выражение. (Скопируйте визуализированную версию, а не уценку, для фактического кода.)

(: [а-z0-9 # $% & '* +/= ^ _ `{|} ~ -!?] + (?:?.!\[А-z0-9 # $% & '* +/= ^ _ `{|} ~ -] +) * | "(:? [\ x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\X5b\x5d- \?? x7f] |\\[\ x01-\x09\x0b\x0c\x0e-\x7f]) *" ) @(: (: [а-z0-9] (: [а-z0-9-] * [а-z0-9]) \) + [а-z0-9] (?.? [а-z0-9 -] * [а-z0-9]) |\[(:(?: (2 (5 [0-5] | [0-4] [0-9]) | 1 [0-9] [0-9] | [1-9] [0-9]?)) \. ) {3} (?:( 2 (5 [0-5] | [0-4] [0-9]) | 1 [0-9] [0-9] |? [1-9] [0-? 9]) | [а-z0-9 -] * [а-z0-9] (: [\ x01-\x08\x0b\x0c\x0e-\x1f\x21-\X5a\x53-\x7f] |\\[\ x01-\x09\x0b\x0c\x0e-\x7f]) +) \])

Вот диаграмма конечный автомат для выше regexp, более понятное, чем регулярное выражение Изображение 4730

Более сложные шаблоны в Perl и PCRE (библиотека регулярных выражений, используемых, например, на PHP) могут правильно разобрать RFC 5322 без заминки. Python и С# тоже могут это сделать, но они используют другой синтаксис из этих первых двух. Однако, если вы вынуждены использовать один из многих менее мощных языков сопоставления шаблонов, тогда лучше всего использовать настоящий парсер.

Также важно понимать, что проверка его в RFC абсолютно ничего не говорит о том, действительно ли этот адрес существует в поставляемом домене, или ли человек, входящий в адрес, является его истинным владельцем. Люди подписывают других до списков рассылки таким образом все время. Фиксирование, требующее более любезной проверки, которая включает отправку этого адреса, сообщение, которое включает токен подтверждения, предназначенный для ввода на той же веб-странице, что и адрес.

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

Для PHP вам не следует использовать шаблон, приведенный в Подтвердить адрес электронной почты с помощью PHP, правильный путь, из которого я цитирую:

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

Это не лучше, чем все другие не-RFC-шаблоны. Он даже не достаточно умен, чтобы обрабатывать даже RFC 822, не говоря уже о RFC 5322. Этот, однако.

Если вы хотите получить фантазию и педантичность, реализовать полный механизм состояния. Регулярное выражение может действовать только как элементарный фильтр. Проблема с регулярными выражениями заключается в том, что кто-то говорит, что их совершенно достоверный адрес электронной почты является недопустимым (ложный положительный результат), потому что ваше регулярное выражение не может справиться с этим, это просто грубо и невежливо с точки зрения пользователя. Механизм состояния для этой цели может как проверять, так и даже исправлять адреса электронной почты, которые в противном случае считались бы недействительными, поскольку он разбирает адрес электронной почты в соответствии с каждым RFC. Это позволяет потенциально более приятный опыт, например

Указанный адрес электронной почты 'myemail @address, com' недействителен. Вы имели в виду '[email protected]'?

См. также Проверка адресов электронной почты, включая комментарии. Или Сравнение адреса электронной почты Проверка регулярных выражений.

Изображение 4731

Демоверсия Debuggex

  • 166
    Вы сказали: «Нет хорошего регулярного выражения». Это общее или особенное для проверки адреса электронной почты?
  • 34
    @ Томалак: только для адресов электронной почты. Как сказал Борцмейер, RFC чрезвычайно сложен
Показать ещё 29 комментариев
707

Нельзя использовать регулярные выражения для проверки адресов электронной почты.

Вместо этого используйте класс MailAddress, например:

try {
    address = new MailAddress(address).Address;
} catch(FormatException) {
    //address is invalid
}

Класс MailAddress использует парсер BNF для проверки адреса в полном соответствии с RFC822.

Если вы действительно хотите использовать регулярное выражение, здесь это:

(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]
)+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:
\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(
?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ 
\t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\0
31]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\
](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+
(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:
(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z
|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)
?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\
r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[
 \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)
?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t]
)*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[
 \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*
)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]
)+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)
*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+
|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r
\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t
]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031
]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](
?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?
:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?
:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?
:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?
[ \t]))*"(?:(?:\r\n)?[ \t])*)*:(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] 
\000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|
\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>

@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"
(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t]
)*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?
:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[
\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-
\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(
?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;
:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([
^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\"
.\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\
]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\
[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\
r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] 
\000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]
|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \0
00-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\
.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,
;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?
:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".
\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[
^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]
]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)(?:,\s*(
?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(
?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[
\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t
])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t
])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?
:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|
\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:
[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\
]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)
?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["
()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)
?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>

@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[
 \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,
;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t]
)*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".
\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:
\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\[
"()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])
*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])
+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\
.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z
|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(
?:\r\n)?[ \t])*))*)?;\s*)
  • 22
    Вы обнаружите, что класс MailAddress в .NET 4.0 гораздо лучше проверяет адреса электронной почты, чем в предыдущих версиях. Я сделал несколько значительных улучшений.
  • 7
    Я думаю, что это вроде ... не работает ... для более простых идентификаторов. a @ b не проверяет. [email protected] совпадает только до ar @ b, .com не совпадает. Однако что-то вроде «Я есть я» @ [10.10.10.10] действительно работает! :)
Показать ещё 18 комментариев
479

Этот вопрос задан очень часто, но я думаю, вам нужно отступить и спросить себя, почему вы хотите синтаксически проверять адреса электронной почты? Какая польза действительно?

  • Он не будет ловить общие опечатки.
  • Это не мешает людям вводить неверные или созданные адреса электронной почты или вводить другой адрес.

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

  • 84
    Возможно, стоит проверить, что они вводили что-то @ что-то в поле при проверке на стороне клиента, чтобы поймать простые ошибки - но в целом вы правы.
  • 5
    Мартин, я дал тебе +1, только чтобы потом прочитать, что foobar @ dk - это действительное письмо. Это было бы не красиво, но если вы хотите быть совместимыми с RFC и использовать здравый смысл, вы должны обнаружить такие случаи и попросить пользователя подтвердить, что это правильно.
Показать ещё 19 комментариев
322

Это зависит от того, что вы имеете в виду: Если вы говорите об улавливании всех допустимых адресов электронной почты, используйте следующее:

(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]
)+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:
\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(
?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ 
\t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\0
31]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\
](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+
(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:
(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z
|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)
?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\
r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[
 \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)
?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t]
)*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[
 \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*
)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]
)+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)
*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+
|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r
\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t
]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031
]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](
?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?
:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?
:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?
:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?
[ \t]))*"(?:(?:\r\n)?[ \t])*)*:(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] 
\000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|
\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>
@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"
(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t]
)*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?
:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[
\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-
\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(
?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;
:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([
^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\"
.\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\
]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\
[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\
r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] 
\000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]
|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \0
00-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\
.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,
;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?
:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".
\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[
^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]
]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)(?:,\s*(
?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(
?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[
\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t
])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t
])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?
:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|
\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:
[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\
]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)
?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["
()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)
?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>
@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[
 \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,
;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t]
)*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".
\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:
\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\[
"()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])
*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])
+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\
.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z
|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(
?:\r\n)?[ \t])*))*)?;\s*)

(http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html) Если вы ищете что-то более простое, но это поймает большинство действительных адресов электронной почты, попробуйте что-то вроде:

"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$"

EDIT: По ссылке:

Это регулярное выражение будет проверять только те адреса, которые были отмечены и заменены пробелами (это выполняется модулем).

  • 10
    Он не соответствует всем адресам, некоторые должны быть преобразованы в первую очередь. По ссылке: «Это регулярное выражение будет проверять только адреса, у которых были удалены все комментарии и заменены пробелами (это делает модуль).»
  • 44
    Можете ли вы привести пример какого-то email address который ошибочно проходит через второй, но перехватывается более длинным регулярным выражением?
Показать ещё 15 комментариев
321

Все зависит от того, насколько вы точны. Для моих целей, когда я просто пытаюсь сохранить такие вещи, как bob @ aol.com (пробелы в сообщениях электронной почты) или steve (без какого-либо домена) или mary@aolcom (без периода до .com), я использую

/^\S+@\S+\.\S+$/

Конечно, это будет соответствовать вещам, которые не являются действительными адресами электронной почты, но это вопрос игры с правилом 90/10.

  • 5
    Он не соответствует foobar @ dk, который является действующим и рабочим адресом электронной почты (хотя, вероятно, большинство почтовых серверов не примут его или добавят что-то.com.)
  • 1
    Да, верно, это не соответствует RFC, но обычно это не проблема.
Показать ещё 11 комментариев
282

[ОБНОВЛЕНО] Я собрал все, что знаю о проверке адреса электронной почты здесь: http://isemail.info, который теперь не только проверяет, но и диагностирует проблемы с адресами электронной почты. Я согласен со многими комментариями здесь, что валидация является лишь частью ответа; см. мое эссе в http://isemail.info/about.

is_email() остается, насколько я знаю, единственным валидатором, который окончательно скажет вам, является ли данная строка допустимым адресом электронной почты или нет. Я загрузил новую версию на http://isemail.info/

Я собрал тестовые примеры от Cal Henderson, Dave Child, Phil Haack, Doug Lovell, RFC5322 и RFC 3696. Всего 275 тестовых адресов. Я провел все эти тесты со всеми бесплатными валидаторами, которые мог найти.

Я постараюсь сохранить эту страницу в актуальном состоянии, так как люди повышают эффективность своих валидаторов. Спасибо Cal, Michael, Dave, Paul и Phil за помощь и сотрудничество в компиляции этих тестов и конструктивной критике в отношении RFC 3696. Три из канонических примеров на самом деле являются неверными адресами. И максимальная длина адреса составляет 254 или 256 символов, не 320.

  • 0
    Этот валидатор также кажется правильным. [... время проходит ...] Хм, похоже, что это просто RFC 5322, а не 3693 или ошибки в нем.
  • 1
    Очень хорошо. Здесь мы не только получаем хорошее эссе, но и тестирующего, а также загружаемую библиотеку. Хороший ответ!
Показать ещё 2 комментария
234

Per спецификация W3C HTML5:

^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$

Context:

A действительный адрес электронной почты - это строка, которая соответствует произведению ABNF [...].

Примечание. Это требование является преднамеренным нарушением RFC 5322, которое определяет синтаксис для адресов электронной почты, которые одновременно слишком строги (до символа "@" ), слишком расплывчатые (после символа "@" ) и слишком слабые (допускающие комментарии, пробельные символы и строки с кавычками в манерах, незнакомых большинству пользователей) для практического использования здесь.

Следующее стандартное выражение, совместимое с JavaScript и Perl, является реализацией указанного выше определения.

/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/

  • 8
    Это интересно. Это нарушение RFC, но преднамеренное и делает sesne. Пример из реальной жизни: gmail игнорирует точки в части до @, поэтому, если ваш адрес электронной почты [email protected], вы можете отправлять электронные письма для теста. @ Gmail.com или test .... @ gmail.com, оба эти адреса недействителен в соответствии с RFC, но действителен в реальном мире.
  • 0
    Я думаю, что последняя часть должна быть '+' вместо '*': ^ [a-zA-Z0-9.! # $% & '* + / =? ^ _ `{|} ~ -] + @ [a- Za-z0-9 -] + (?:. \ [A-Za-Z0-9 -] +) + $
Показать ещё 6 комментариев
204

Легко в Perl 5.10 или новее:

/(?(DEFINE)
   (?<address>         (?&mailbox) | (?&group))
   (?<mailbox>         (?&name_addr) | (?&addr_spec))
   (?<name_addr>       (?&display_name)? (?&angle_addr))
   (?<angle_addr>      (?&CFWS)? < (?&addr_spec) > (?&CFWS)?)
   (?<group>           (?&display_name) : (?:(?&mailbox_list) | (?&CFWS))? ;
                                          (?&CFWS)?)
   (?<display_name>    (?&phrase))
   (?<mailbox_list>    (?&mailbox) (?: , (?&mailbox))*)

   (?<addr_spec>       (?&local_part) \@ (?&domain))
   (?<local_part>      (?&dot_atom) | (?&quoted_string))
   (?<domain>          (?&dot_atom) | (?&domain_literal))
   (?<domain_literal>  (?&CFWS)? \[ (?: (?&FWS)? (?&dcontent))* (?&FWS)?
                                 \] (?&CFWS)?)
   (?<dcontent>        (?&dtext) | (?&quoted_pair))
   (?<dtext>           (?&NO_WS_CTL) | [\x21-\x5a\x5e-\x7e])

   (?<atext>           (?&ALPHA) | (?&DIGIT) | [!#\$%&'*+-/=?^_`{|}~])
   (?<atom>            (?&CFWS)? (?&atext)+ (?&CFWS)?)
   (?<dot_atom>        (?&CFWS)? (?&dot_atom_text) (?&CFWS)?)
   (?<dot_atom_text>   (?&atext)+ (?: \. (?&atext)+)*)

   (?<text>            [\x01-\x09\x0b\x0c\x0e-\x7f])
   (?<quoted_pair>     \\ (?&text))

   (?<qtext>           (?&NO_WS_CTL) | [\x21\x23-\x5b\x5d-\x7e])
   (?<qcontent>        (?&qtext) | (?&quoted_pair))
   (?<quoted_string>   (?&CFWS)? (?&DQUOTE) (?:(?&FWS)? (?&qcontent))*
                        (?&FWS)? (?&DQUOTE) (?&CFWS)?)

   (?<word>            (?&atom) | (?&quoted_string))
   (?<phrase>          (?&word)+)

   # Folding white space
   (?<FWS>             (?: (?&WSP)* (?&CRLF))? (?&WSP)+)
   (?<ctext>           (?&NO_WS_CTL) | [\x21-\x27\x2a-\x5b\x5d-\x7e])
   (?<ccontent>        (?&ctext) | (?&quoted_pair) | (?&comment))
   (?<comment>         \( (?: (?&FWS)? (?&ccontent))* (?&FWS)? \) )
   (?<CFWS>            (?: (?&FWS)? (?&comment))*
                       (?: (?:(?&FWS)? (?&comment)) | (?&FWS)))

   # No whitespace control
   (?<NO_WS_CTL>       [\x01-\x08\x0b\x0c\x0e-\x1f\x7f])

   (?<ALPHA>           [A-Za-z])
   (?<DIGIT>           [0-9])
   (?<CRLF>            \x0d \x0a)
   (?<DQUOTE>          ")
   (?<WSP>             [\x20\x09])
 )

 (?&address)/x
  • 16
    Хотелось бы увидеть это в Python
  • 4
    Я думаю, что только подмножество части addrspec действительно имеет отношение к вопросу. Принятие чего-то большего и переадресация, хотя какая-то другая часть системы, которая не готова принять полные адреса RFC5822, похожа на стрельбу - ваша собственная нога.
Показать ещё 3 комментария
137

Не знаю о лучшем, но этот один, по крайней мере, правильный, если адреса оставляют свои комментарии и заменены пробелами.

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

  • 2
    Насколько я знаю, некоторые библиотеки тоже не правы. Я смутно помню, что в PHP PEAR была такая ошибка.
  • 0
    На этой странице также есть заявление об отказе от некоторых вещей из спецификации. что регулярное выражение не поддерживает.
Показать ещё 2 комментария
134

Я использую

^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$

Какой из них используется в ASP.NET с помощью параметра RegularExpressionValidator.

  • 22
    Бу! Мой (опрометчивый) адрес [email protected] отклонен.
  • 83
    Таким образом, в основном, это не позволяет смешные адреса электронной почты. :)
Показать ещё 8 комментариев
110

Адреса электронной почты, которые я хочу проверить, будут использоваться веб-приложением ASP.NET с использованием пространства имен System.Net.Mail для отправки электронных писем в список людей. Поэтому вместо того, чтобы использовать какое-то очень сложное регулярное выражение, я просто пытаюсь создать экземпляр MailAddress с адреса. Контрактор MailAddress генерирует исключение, если адрес не сформирован должным образом. Таким образом, я знаю, что, по крайней мере, я могу получить электронную почту за дверью. Конечно, это проверка на стороне сервера, но, как минимум, вам это нужно.

protected void emailValidator_ServerValidate(object source, ServerValidateEventArgs args)
{
    try
    {
        var a = new MailAddress(txtEmail.Text);
    }
    catch (Exception ex)
    {
        args.IsValid = false;
        emailValidator.ErrorMessage = "email: " + ex.Message;
    }
}
  • 3
    Хороший вопрос. Даже если эта проверка сервера отклоняет какой-либо действительный адрес, это не является проблемой, так как вы все равно не сможете отправить на этот адрес с использованием этой конкретной серверной технологии. Или вы можете попробовать сделать то же самое, используя стороннюю библиотеку электронной почты, которую вы используете вместо инструментов по умолчанию.
  • 0
    Мне действительно нравится, как это использует .NET Framework - нет смысла изобретать велосипед. Это отлично. Просто, чисто и гарантирует, что вы действительно можете отправить электронное письмо. Отличная работа.
Показать ещё 2 комментария
97

Быстрый ответ

Используйте следующее regex для проверки ввода:

([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)+

Адреса, соответствующие этому регулярному выражению:

  • имеют локальную часть (т.е. часть перед @-знаком), которая строго соответствует RFC 5321/5322,
  • имеют часть домена (т.е. часть после @-знака), которая является именем хоста с по меньшей мере двумя метками, каждая из которых имеет длину не более 63 символов.

Второе ограничение является ограничением на RFC 5321/5322.

Подробный ответ

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

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

Синтаксис адресов электронной почты был определен в различных RFC, в первую очередь RFC 822 и RFC 5322. RFC 822 следует рассматривать как "оригинальный" стандарт и RFC 5322 как последний стандарт. Синтаксис, определенный в RFC 822, является самым мягким, а последующие стандарты ограничивают синтаксис дальше и дальше, когда новые системы или службы должны распознавать устаревший синтаксис, но никогда не создавать его.

В этом ответе я беру "адрес электронной почты" в значение addr-spec, как определено в RFC (т.е. [email protected], но не "John Doe"<[email protected]>, а не some-group:[email protected],[email protected];).

Есть одна проблема с переводом синтаксиса RFC в регулярные выражения: синтаксисы не являются регулярными! Это связано с тем, что они допускают дополнительные комментарии в адресах электронной почты, которые могут быть бесконечно вложены, в то время как бесконечное вложение не может быть описано регулярным выражением. Чтобы сканировать или проверять адреса, содержащие комментарии, вам нужен синтаксический анализатор или более мощные выражения. (Обратите внимание, что такие языки, как Perl, имеют конструкты для описания контекстно-свободных грамматик по-примеру). В этом ответе я буду игнорировать комментарии и учитывать только правильные регулярные выражения.

RFC определяют синтаксисы для сообщений электронной почты, а не для адресов электронной почты как таковых. Адреса могут отображаться в разных полях заголовка, и именно там они определяются в первую очередь. Когда они появляются в заголовках, адреса могут содержать (между лексическими токенами) пробелы, комментарии и даже разрывы строк. Семантически это не имеет никакого значения. Удалив это пробелы и т.д. Из адреса, вы получите семантически эквивалентное каноническое представление. Таким образом, каноническое представление first. last (comment) @ [3.5.7.9] составляет first.last@[3.5.7.9].

Различные синтаксисы должны использоваться для разных целей. Если вы хотите сканировать адреса электронной почты в (возможно, очень старом) документе, может быть хорошей идеей использовать синтаксис, определенный в RFC 822. С другой стороны, если вы хотите проверить ввод пользователя, вы можете использовать синтаксис, определенный в RFC 5322, возможно, только прием канонических представлений. Вы должны решить, какой синтаксис применим к вашему конкретному случаю.

Я использую POSIX "расширенные" регулярные выражения в этом ответе, предполагая набор символов, совместимый с ASCII.

RFC 822

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

([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]))*(\\\r)*")(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]))*(\\\r)*"))*@([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]))*(\\\r)*])(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]))*(\\\r)*]))*

Я считаю, что он полностью соответствует RFC 822, включая errata. Он распознает адреса электронной почты только в своей канонической форме. Для регулярного выражения, которое распознает (складывающиеся) пробелы, см. Вывод ниже.

Вывод показывает, как я пришел к выражению. Я перечисляю все соответствующие правила грамматики из RFC точно так, как они появляются, а затем соответствующее регулярное выражение. Там, где был опубликован erratum, я даю отдельное выражение для исправленного правила грамматики (помечено как "erratum" ) и использует обновленную версию в качестве подвыражения в последующих регулярных выражениях.

Как указано в пункте 3.1.4. из RFC 822 необязательное линейное белое пространство может быть вставлено между лексическими токенами. Там, где это применимо, я расширил выражения для размещения этого правила и пометил результат с помощью "opt-lwsp".

CHAR        =  <any ASCII character>
            =~ .

CTL         =  <any ASCII control character and DEL>
            =~ [\x00-\x1F\x7F]

CR          =  <ASCII CR, carriage return>
            =~ \r

LF          =  <ASCII LF, linefeed>
            =~ \n

SPACE       =  <ASCII SP, space>
            =~  

HTAB        =  <ASCII HT, horizontal-tab>
            =~ \t

<">         =  <ASCII quote mark>
            =~ "

CRLF        =  CR LF
            =~ \r\n

LWSP-char   =  SPACE / HTAB
            =~ [ \t]

linear-white-space =  1*([CRLF] LWSP-char)
                   =~ ((\r\n)?[ \t])+

specials    =  "(" / ")" / "<" / ">" / "@" /  "," / ";" / ":" / "\" / <"> /  "." / "[" / "]"
            =~ [][()<>@,;:\\".]

quoted-pair =  "\" CHAR
            =~ \\.

qtext       =  <any CHAR excepting <">, "\" & CR, and including linear-white-space>
            =~ [^"\\\r]|((\r\n)?[ \t])+

dtext       =  <any CHAR excluding "[", "]", "\" & CR, & including linear-white-space>
            =~ [^][\\\r]|((\r\n)?[ \t])+

quoted-string  =  <"> *(qtext|quoted-pair) <">
               =~ "([^"\\\r]|((\r\n)?[ \t])|\\.)*"
(erratum)      =~ "(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*"

domain-literal =  "[" *(dtext|quoted-pair) "]"
               =~ \[([^][\\\r]|((\r\n)?[ \t])|\\.)*]
(erratum)      =~ \[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*]

atom        =  1*<any CHAR except specials, SPACE and CTLs>
            =~ [^][()<>@,;:\\". \x00-\x1F\x7F]+

word        =  atom / quoted-string
            =~ [^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*"

domain-ref  =  atom

sub-domain  =  domain-ref / domain-literal
            =~ [^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*]

local-part  =  word *("." word)
            =~ ([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*")(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*"))*
(opt-lwsp)  =~ ([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*")(((\r\n)?[ \t])*\.((\r\n)?[ \t])*([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*"))*

domain      =  sub-domain *("." sub-domain)
            =~ ([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*])(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*]))*
(opt-lwsp)  =~ ([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*])(((\r\n)?[ \t])*\.((\r\n)?[ \t])*([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*]))*

addr-spec   =  local-part "@" domain
            =~ ([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*")(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*"))*@([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*])(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*]))*
(opt-lwsp)  =~ ([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*")((\r\n)?[ \t])*(\.((\r\n)?[ \t])*([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*")((\r\n)?[ \t])*)*@((\r\n)?[ \t])*([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*])(((\r\n)?[ \t])*\.((\r\n)?[ \t])*([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*]))*
(canonical) =~ ([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]))*(\\\r)*")(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]))*(\\\r)*"))*@([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]))*(\\\r)*])(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]))*(\\\r)*]))*

RFC 5322

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

([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|\[[\t -Z^-~]*])

Я считаю, что он полностью соответствует RFC 5322, включая errata. Он распознает адреса электронной почты только в своей канонической форме. Для регулярного выражения, которое распознает (складывающиеся) пробелы, см. Вывод ниже.

Вывод показывает, как я пришел к выражению. Я перечисляю все соответствующие правила грамматики из RFC точно так, как они появляются, а затем соответствующее регулярное выражение. Для правил, которые содержат семантически нерелевантные (складывающиеся) пробелы, я даю отдельное регулярное выражение с надписью "(нормализованное)", которое не принимает это пробел.

Я проигнорировал все "obs-" правила из RFC. Это означает, что регулярные выражения соответствуют только адресам электронной почты, которые строго соответствуют требованиям RFC 5322. Если вам нужно сопоставить "старые" адреса (поскольку существует более свободная грамматика, включая правила "obs-" ), вы можете использовать одно из RFE 822 регулярных выражений из предыдущего абзаца.

VCHAR           =   %x21-7E
                =~  [!-~]

ALPHA           =   %x41-5A / %x61-7A
                =~  [A-Za-z]

DIGIT           =   %x30-39
                =~  [0-9]

HTAB            =   %x09
                =~  \t

CR              =   %x0D
                =~  \r

LF              =   %x0A
                =~  \n

SP              =   %x20
                =~  

DQUOTE          =   %x22
                =~  "

CRLF            =   CR LF
                =~  \r\n

WSP             =   SP / HTAB
                =~  [\t ]

quoted-pair     =   "\" (VCHAR / WSP)
                =~  \\[\t -~]

FWS             =   ([*WSP CRLF] 1*WSP)
                =~  ([\t ]*\r\n)?[\t ]+

ctext           =   %d33-39 / %d42-91 / %d93-126
                =~  []!-'*-[^-~]

("comment" is left out in the regex)
ccontent        =   ctext / quoted-pair / comment
                =~  []!-'*-[^-~]|(\\[\t -~])

(not regular)
comment         =   "(" *([FWS] ccontent) [FWS] ")"

(is equivalent to FWS when leaving out comments)
CFWS            =   (1*([FWS] comment) [FWS]) / FWS
                =~  ([\t ]*\r\n)?[\t ]+

atext           =   ALPHA / DIGIT / "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}" / "~"
                =~  [-!#-'*+/-9=?A-Z^-~]

dot-atom-text   =   1*atext *("." 1*atext)
                =~  [-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*

dot-atom        =   [CFWS] dot-atom-text [CFWS]
                =~  (([\t ]*\r\n)?[\t ]+)?[-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*(([\t ]*\r\n)?[\t ]+)?
(normalized)    =~  [-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*

qtext           =   %d33 / %d35-91 / %d93-126
                =~  []!#-[^-~]

qcontent        =   qtext / quoted-pair
                =~  []!#-[^-~]|(\\[\t -~])

(erratum)
quoted-string   =   [CFWS] DQUOTE ((1*([FWS] qcontent) [FWS]) / FWS) DQUOTE [CFWS]
                =~  (([\t ]*\r\n)?[\t ]+)?"(((([\t ]*\r\n)?[\t ]+)?([]!#-[^-~]|(\\[\t -~])))+(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?)"(([\t ]*\r\n)?[\t ]+)?
(normalized)    =~  "([]!#-[^-~ \t]|(\\[\t -~]))+"

dtext           =   %d33-90 / %d94-126
                =~  [!-Z^-~]

domain-literal  =   [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
                =~  (([\t ]*\r\n)?[\t ]+)?\[((([\t ]*\r\n)?[\t ]+)?[!-Z^-~])*(([\t ]*\r\n)?[\t ]+)?](([\t ]*\r\n)?[\t ]+)?
(normalized)    =~  \[[\t -Z^-~]*]

local-part      =   dot-atom / quoted-string
                =~  (([\t ]*\r\n)?[\t ]+)?[-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?"(((([\t ]*\r\n)?[\t ]+)?([]!#-[^-~]|(\\[\t -~])))+(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?)"(([\t ]*\r\n)?[\t ]+)?
(normalized)    =~  [-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+"

domain          =   dot-atom / domain-literal
                =~  (([\t ]*\r\n)?[\t ]+)?[-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?\[((([\t ]*\r\n)?[\t ]+)?[!-Z^-~])*(([\t ]*\r\n)?[\t ]+)?](([\t ]*\r\n)?[\t ]+)?
(normalized)    =~  [-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|\[[\t -Z^-~]*]

addr-spec       =   local-part "@" domain
                =~  ((([\t ]*\r\n)?[\t ]+)?[-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?"(((([\t ]*\r\n)?[\t ]+)?([]!#-[^-~]|(\\[\t -~])))+(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?)"(([\t ]*\r\n)?[\t ]+)?)@((([\t ]*\r\n)?[\t ]+)?[-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?\[((([\t ]*\r\n)?[\t ]+)?[!-Z^-~])*(([\t ]*\r\n)?[\t ]+)?](([\t ]*\r\n)?[\t ]+)?)
(normalized)    =~  ([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|\[[\t -Z^-~]*])

Обратите внимание, что некоторые источники (особенно w3c) утверждают, что RFC 5322 слишком строг в локальной части (т.е. часть перед @-знаком). Это происходит потому, что "..", "a..b" и "a". являются недопустимыми точечными атомами, в то время как они могут использоваться как имена почтовых ящиков. Однако RFC разрешает локальные части, подобные этим, за исключением того, что они должны быть указаны. Поэтому вместо [email protected] вы должны написать "a..b"@example.net, который семантически эквивалентен.

Дальнейшие ограничения

SMTP (как определено в RFC 5321) дополнительно ограничивает набор допустимых адресов электронной почты (или фактически: имена почтовых ящиков). Кажется разумным навязывать эту более строгую грамматику, так что соответствующий адрес электронной почты может быть фактически использован для отправки электронной почты.

RFC 5321 в основном оставляет только "локальную" часть (т.е. часть перед @-знаком), но более строгая на части домена (т.е. часть после @-знака). Он разрешает вместо имен доменов вместо имен точек вместо точек-атомов и адресных литералов.

Грамматика, представленная в RFC 5321, слишком мягка, когда речь идет об именах хостов и IP-адресах. Я взял на себя смелость "исправить" рассматриваемые правила, используя этот проект и RFC 1034 в качестве рекомендаций. Здесь полученное регулярное выражение.

([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)*|\[((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|IPv6:((((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){6}|::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){5}|[0-9A-Fa-f]{0,4}::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){4}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):)?(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){3}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,2}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){2}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,3}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,4}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,5}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)|(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+)])

Обратите внимание, что в зависимости от варианта использования вы можете не захотеть разрешить "общий-адрес-литерал" в вашем регулярном выражении. Также обратите внимание, что я использовал отрицательный lookahead (?!IPv6:) в финальном регулярном выражении, чтобы не допустить, чтобы часть "Общий-адрес-литерал" соответствовала неправильным адресам IPv6. Некоторые процессоры regex не поддерживают отрицательный результат. Удалите подстроку |(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+ из регулярного выражения, если вы хотите удалить всю часть "Общий адрес-буквал".

Здесь вывод:

Let-dig         =   ALPHA / DIGIT
                =~  [0-9A-Za-z]

Ldh-str         =   *( ALPHA / DIGIT / "-" ) Let-dig
                =~  [0-9A-Za-z-]*[0-9A-Za-z]

(regex is updated to make sure sub-domains are max. 63 charactes long - RFC 1034 section 3.5)
sub-domain      =   Let-dig [Ldh-str]
                =~  [0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?

Domain          =   sub-domain *("." sub-domain)
                =~  [0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)*

Snum            =   1*3DIGIT
                =~  [0-9]{1,3}

(suggested replacement for "Snum")
ip4-octet       =   DIGIT / %x31-39 DIGIT / "1" 2DIGIT / "2" %x30-34 DIGIT / "25" %x30-35
                =~  25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]

IPv4-address-literal    =   Snum 3("."  Snum)
                        =~  [0-9]{1,3}(\.[0-9]{1,3}){3}

(suggested replacement for "IPv4-address-literal")
ip4-address     =   ip4-octet 3("." ip4-octet)
                =~  (25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}

(suggested replacement for "IPv6-hex")
ip6-h16         =   "0" / ( (%x49-57 / %x65-70 /%x97-102) 0*3(%x48-57 / %x65-70 /%x97-102) )
                =~  0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}

(not from RFC)
ls32            =   ip6-h16 ":" ip6-h16 / ip4-address
                =~  (0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}

(suggested replacement of "IPv6-addr")
ip6-address     =                                      6(ip6-h16 ":") ls32
                    /                             "::" 5(ip6-h16 ":") ls32
                    / [                 ip6-h16 ] "::" 4(ip6-h16 ":") ls32
                    / [ *1(ip6-h16 ":") ip6-h16 ] "::" 3(ip6-h16 ":") ls32
                    / [ *2(ip6-h16 ":") ip6-h16 ] "::" 2(ip6-h16 ":") ls32
                    / [ *3(ip6-h16 ":") ip6-h16 ] "::"   ip6-h16 ":"  ls32
                    / [ *4(ip6-h16 ":") ip6-h16 ] "::"                ls32
                    / [ *5(ip6-h16 ":") ip6-h16 ] "::"   ip6-h16
                    / [ *6(ip6-h16 ":") ip6-h16 ] "::"
                =~  (((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){6}|::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){5}|[0-9A-Fa-f]{0,4}::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){4}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):)?(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){3}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,2}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){2}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,3}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,4}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,5}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::

IPv6-address-literal    =   "IPv6:" ip6-address
                        =~  IPv6:((((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){6}|::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){5}|[0-9A-Fa-f]{0,4}::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){4}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):)?(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){3}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,2}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){2}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,3}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,4}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,5}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)

Standardized-tag        =   Ldh-str
                        =~  [0-9A-Za-z-]*[0-9A-Za-z]

dcontent        =   %d33-90 / %d94-126
                =~  [!-Z^-~]

General-address-literal =   Standardized-tag ":" 1*dcontent
                        =~  [0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+

address-literal =   "[" ( IPv4-address-literal / IPv6-address-literal / General-address-literal ) "]"
                =~  \[((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|IPv6:((((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){6}|::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){5}|[0-9A-Fa-f]{0,4}::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){4}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):)?(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){3}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,2}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){2}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,3}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,4}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,5}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)|(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+)]

Mailbox         =   Local-part "@" ( Domain / address-literal )
                =~  ([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)*|\[((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|IPv6:((((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){6}|::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){5}|[0-9A-Fa-f]{0,4}::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){4}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):)?(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){3}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,2}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){2}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,3}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,4}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,5}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)|(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+)])

Подтверждение ввода пользователя

Общим примером использования является проверка ввода пользователя, например, в форме html. В этом случае обычно разумно исключать адресные литералы и требовать по меньшей мере двух меток в имени хоста. Взяв улучшенное регулярное выражение RFC 5321 из предыдущего раздела в качестве основы, получившееся выражение будет выглядеть следующим образом:

([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)+

Я не рекомендую ограничивать местную часть дальше, например. путем исключения цитируемых строк, поскольку мы не знаем, какие имена почтовых ящиков разрешают некоторым хостам (например, "a..b"@example.net или даже "a b"@example.net).

Я также не рекомендую явно проверять список литеральных доменов верхнего уровня или даже налагать ограничения по длине (помните, как ".museum" недействителен [a-z]{2,4}), но если вы должны:

([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?\.)*(net|org|com|info| и т.д... )

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

Дальнейшие соображения

Если только принять имена хостов в доменной части (после @-знака), приведенные выше выражения принимают только метки длиной не более 63 символов, как и должны. Однако они не применяют тот факт, что для всего имени хоста должно быть не более 253 символов (включая точки). Хотя это ограничение строго говоря, остается регулярным, не представляется возможным создать регулярное выражение, которое включает это правило.

Еще одно соображение, особенно при использовании регулярных выражений для проверки ввода, - это обратная связь с пользователем. Если пользователь вводит неверный адрес, было бы неплохо дать немного больше отзывов, чем простой "синтаксически неправильный адрес". С "vanilla" regexes это невозможно.

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

Ни одно из регулярных выражений в этом ответе не оптимизировано для производительности. Если производительность является проблемой, вы должны убедиться, что (и как) можно оптимизировать регулярное выражение по вашему выбору.

  • 3
    RFC 6532 обновляет 5322, чтобы включить и включить полный, чистый UTF-8. Дополнительные подробности здесь .
  • 0
    Согласно википедии, кажется, что локальная часть, если она пунктирная, имеет ограничение в 64 символа на часть, а также RFC 5322 относится к пунктирной локальной части, которая должна интерпретироваться с ограничениями доменов. Например, arbitrary-long-email-address-should-be-invalid-arbitrary-long-email-address-should-be-invalid.and-the-second-group-also-should-not-be-so-long-and-the-second-group-also-should-not-be-so-long@example.com не должны проверяться. Я предлагаю изменить знаки «+» в первой группе (имя перед необязательной точкой) и во второй группе (имя после следующих точек) на {1,64}
Показать ещё 3 комментария
70

Есть много примеров этого в сети (и я думаю, что даже тот, который полностью проверяет RFC), но он содержит десятки/сотни строк, если память используется). Люди склонны увлекаться проверкой такого рода вещей. Почему бы просто не проверить, что у него есть @и по крайней мере один. и соответствует некоторой простой минимальной длине. Тривиально вводить поддельное письмо и все равно соответствовать любому действительному регулярному выражению. Я бы предположил, что ложные срабатывания лучше ложных негативов.

  • 1
    Да, но какой RFC? :) Этот [RFC-5322-валидатор] ( stackoverflow.com/questions/201323/… ) имеет длину всего около сорока строк.
  • 14
    А. не требуется. У TLD могут быть адреса электронной почты или адрес IPv6.
Показать ещё 1 комментарий
64

При принятии решения о том, какие символы разрешены, помните своих апострофов и друзей с переносом. Я не контролирую тот факт, что моя компания генерирует мой адрес электронной почты, используя мое имя из системы HR. Это включает апостроф в моей фамилии. Я не могу сказать, сколько раз я был заблокирован от взаимодействия с веб-сайтом из-за того, что мой адрес электронной почты "недействителен".

  • 4
    Это очень распространенная проблема в программах, которые делают необоснованные предположения о том, что есть и что не разрешено на имя человека. Никто не должен делать такие предположения, просто принять любой характер, который, по мнению соответствующих RFC, необходимо.
  • 4
    Да. Я особенно взбешен тем, что программисты отвергают заглавные буквы в адресах электронной почты! Глупо и / или лениво.
61

Это регулярное выражение из Perl Email:: Valid. Я считаю, что это самый точный, он соответствует всем 822. И он основан на регулярном выражении в книге О'Рейли:

Регулярное выражение, построенное с использованием примера Джеффри Фридла в Освоение регулярных выражений (http://www.ora.com/catalog/regexp/).

$RFC822PAT = <<'EOF';
[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\
xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xf
f\n\015()]*)*\)[\040\t]*)*(?:(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\x
ff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015
"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\040\t]*(?:\([^\\\x80-\
xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80
-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*
)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\
\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\
x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x8
0-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n
\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\040\t]*(?:\([^\\\x
80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^
\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040
\t]*)*)*@[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([
^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\
\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\
x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-
\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()
]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\
x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\04
0\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\
n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\
015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?!
[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\
]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\
x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\01
5()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*|(?:[^(\040)<>@,;:".
\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]
)|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[^
()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037]*(?:(?:\([^\\\x80-\xff\n\0
15()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][
^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)|"[^\\\x80-\xff\
n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[^()<>@,;:".\\\[\]\
x80-\xff\000-\010\012-\037]*)*<[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?
:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-
\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:@[\040\t]*
(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015
()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()
]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\0
40)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\
[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\
xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*
)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80
-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x
80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t
]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\
\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])
*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x
80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80
-\xff\n\015()]*)*\)[\040\t]*)*)*(?:,[\040\t]*(?:\([^\\\x80-\xff\n\015(
)]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\
\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*@[\040\t
]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\0
15()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015
()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(
\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|
\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80
-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()
]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x
80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^
\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040
\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".
\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff
])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\
\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x
80-\xff\n\015()]*)*\)[\040\t]*)*)*)*:[\040\t]*(?:\([^\\\x80-\xff\n\015
()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\
\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)?(?:[^
(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-
\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\
n\015"]*)*")[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|
\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))
[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff
\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\x
ff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(
?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\
000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\
xff\n\015"]*)*")[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\x
ff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)
*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*@[\040\t]*(?:\([^\\\x80-\x
ff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-
\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)
*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\
]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\]
)[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-
\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\x
ff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(
?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80
-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<
>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x8
0-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:
\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]
*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)
*\)[\040\t]*)*)*>)
EOF
  • 12
    О_О вам также нужно быть мастером регулярных выражений, чтобы понять, что он делает
46

Как вы пишете на PHP, я бы посоветовал вам использовать проверку встроенного PHP для писем.

filter_var($value, FILTER_VALIDATE_EMAIL)

Если вы используете php-версию ниже 5.3.6, пожалуйста, обратите внимание на эту проблему: https://bugs.php.net/bug.php?id=53091

Если вам нужна дополнительная информация о том, как работает эта проверка подлинности в buid-in, см. здесь: Действительно ли работает PHP filter_var FILTER_VALIDATE_EMAIL?

  • 0
    получает голос, именно то, что я собирался сказать. Не обрабатывает IDN, но преобразование в маленький код заранее решает это. В PHP> = 5.3 для этого есть idn_to_ascii (). Один из лучших и самых простых способов проверки электронной почты.
43

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

  • 1
    Это было отмечено для длины и содержания, но это все еще хороший вклад с 41 голосом и не должен быть удален.
40

Cal Henderson (Flickr) написал статью под названием Разбор адресов электронной почты в PHP и показывает, как правильно выполнять RFC (2) 822-совместимый анализ адресов электронной почты. Вы также можете получить исходный код в php, python и ruby, который лицензия cc.

  • 0
    он сказал мне, что a@b был действительным
  • 1
    @dsdsdsdsd Поскольку a@b допустимо ... в этом случае b является доменом верхнего уровня.
38

Существует не тот, который действительно полезен. Я обсуждаю некоторые проблемы в моем Ответ на Есть ли библиотека php для проверки адреса электронной почты?, обсуждается также в Regexp распознавание адреса электронной почты трудно?

Короче говоря, не ожидайте, что одно полезное регулярное выражение будет работать правильно. И лучшее регулярное выражение будет проверять синтаксис, а не действительность электронной почты ([email protected] верен, но он, вероятно, будет отказываться...).

  • 0
    Поправьте меня, если я ошибаюсь, но я считаю, что PHP использует шаблоны PCRE. Если это так, вы сможете создать нечто похожее на паттерн Abigail RFC 5322 .
  • 0
    @tchrist: не уверен, догнал ли PCRE этот синтаксис (который я обнаружил). Если это так, не уверен, что PHP PCRE догнал эту версию PCRE ... Что ж, если я правильно понимаю этот синтаксис, вы также можете использовать PEG-парсер, намного более понятный и полный, чем регулярное выражение в любом случае.
Показать ещё 1 комментарий
32

Одно простое регулярное выражение, которое, по крайней мере, не отклоняло бы какой-либо действительный адрес электронной почты, будет проверять что-то, а затем знак @, а затем что-то, за которым следует период и как минимум 2 somethings. Он ничего не отклонит, но после рассмотрения спецификации я не могу найти письмо, которое было бы действительным и отклонено.

email = ~ /.+@[^@]+\.[^@]{2,}$/

  • 3
    Это то, что я искал. Не очень ограничительно, но гарантирует, что есть только 1 @ (так как мы разбираем список и хотим убедиться, что нет пропущенных запятых). К вашему сведению, вы можете иметь @ слева, если оно в кавычках: Valid_email_addresses , но это довольно бахромой.
  • 2
    После использования понял, что это не работает точно. /^[^@]+@[^@]+\.[^@]{2}[^@]*$/ ^@]* /^[^@]+@[^@]+\.[^@]{2}[^@]*$/ фактически проверяет наличие 1 @ знака. Ваше регулярное выражение пропустит множественное число из-за. * В конце.
Показать ещё 4 комментария
28

Вы можете использовать тот, который используется плагином jQuery Validation:

/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i
24

Для наиболее полной оценки лучшего регулярного выражения для проверки адреса электронной почты см. эту ссылку; " Сравнение адреса электронной почты с проверкой регулярных выражений

Вот текущее верхнее выражение для ссылочных целей:

/^([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$/i
  • 0
    spoon16: Эта ссылка не совсем правильная. Заявление о том, что не может быть идеального шаблона для проверки адресов электронной почты, явно ошибочно. Вы можете , но вы должны убедиться, что вы следуете RFC вплоть до буквы. И вы должны выбрать правильный RFC тоже.
  • 0
    «Лучший» в настоящее время не работает с регулярным выражением Java - даже после правильного экранирования и преобразования строки.
21

Не говоря уже о том, что нелатинские (китайские, арабские, греческие, ивриты, кириллицы и т.д.) доменные имена должны быть разрешены в в ближайшем будущем. Каждый должен изменить используемое регулярное выражение электронной почты, потому что эти символы, несомненно, не будут покрываться [a-z]/i и \w. Они все потерпят неудачу.

В конце концов, лучший способ проверки адреса электронной почты по-прежнему отправляет электронное письмо на указанный адрес для проверки адреса. Если адрес электронной почты является частью аутентификации пользователя (register/login/etc), вы можете идеально комбинировать его с системой активации пользователя. То есть отправьте электронное письмо со ссылкой с уникальным ключом активации на указанный адрес электронной почты и разрешите только регистрацию, когда пользователь активировал вновь созданную учетную запись, используя ссылку в письме.

Если целью регулярного выражения является простое информирование пользователя в пользовательском интерфейсе, что указанный адрес электронной почты не выглядит в нужном формате, лучше всего проверить, соответствует ли оно в основном следующее регулярное выражение:

^([^.@]+)(\.[^.@]+)*@([^.@]+\.)+([^.@]+)$

Просто. Почему бы вам не беспокоиться о персонажах, используемых в названии и домене? Ответственность клиента заключается в том, чтобы ввести действительный адрес электронной почты, а не сервер. Даже когда клиент вводит синтаксически правильный адрес электронной почты, например [email protected], это не гарантирует, что он является законным адресом электронной почты. Никакое регулярное выражение не может покрыть это.

  • 4
    Я согласен, что отправка сообщения аутентификации, как правило, является лучшим способом для такого рода вещей, синтаксически правильные и действительные не совпадают. Я расстраиваюсь, когда меня заставляют дважды вводить свой адрес электронной почты для «Подтверждения», как будто я не могу посмотреть, что я напечатал. В любом случае, я копирую только первое во второе, оно, похоже, все больше используется.
  • 0
    согласна! но это регулярное выражение, я не думаю, является действительным, потому что оно позволяет spaces после @. например. [email protected] com net считает действительным электронное письмо, используя приведенное выше регулярное выражение, где оно должно возвращать недействительное.
16

Спецификация HTML5 предлагает простое регулярное выражение для проверки адресов электронной почты:

/^[a-zA-Z0-9.!#$%&'*+\/=?^_'{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/

Это намеренно не соответствует RFC 5322.

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

Общая длина также может быть ограничена 254 символами, в соответствии с исправлением 1690 RFC 3696.

  • 0
    Лучший ответ! Вот ссылка на рекомендацию w3: w3.org/TR/html5/forms.html#valid-e-mail-address. Это регулярное выражение используется многими браузерами.
  • 2
    Это ТАК не лучший ответ! Этот шаблон соответствует этому совершенно invalid@emailaddress адресу: invalid@emailaddress . Я призываю к осторожности и много испытаний, прежде чем использовать его!
Показать ещё 3 комментария
14

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

Это задание для синтаксического анализатора, но даже если адрес синтаксически действителен, он все равно может быть невозможен. Иногда вам приходится прибегать к методу горбатых "Эй, y'all, смотреть ee-us!"

// derivative of work with the following copyright and license:
// Copyright (c) 2004 Casey West.  All rights reserved.
// This module is free software; you can redistribute it and/or
// modify it under the same terms as Perl itself.

// see http://search.cpan.org/~cwest/Email-Address-1.80/

private static string gibberish = @"
(?-xism:(?:(?-xism:(?-xism:(?-xism:(?-xism:(?-xism:(?-xism:\
s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^
\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))
|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+
|\s+)*[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+(?-xism:(?-xism:\
s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^
\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))
|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+
|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(
?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?
:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x
0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*<DQ>(?-xism:(?-xism:[
^\\<DQ>])|(?-xism:\\(?-xism:[^\x0A\x0D])))+<DQ>(?-xism:(?-xi
sm:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xis
m:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\
]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\
s*)+|\s+)*))+)?(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?
-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:
\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[
^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*<(?-xism:(?-xi
sm:(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^(
)\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(
?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))
|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*(?-xism:[^\x00-\x1F\x7F()<
>\[\]:;@\,.<DQ>\s]+(?:\.[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]
+)*)(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))
|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:
(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s
*\)\s*))+)*\s*\)\s*)+|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((?
:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x
0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xi
sm:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*
<DQ>(?-xism:(?-xism:[^\\<DQ>])|(?-xism:\\(?-xism:[^\x0A\x0D]
)))+<DQ>(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\
]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-x
ism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+
)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*))\@(?-xism:(?-xism:(?-xism:(
?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?
-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^
()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s
*\)\s*)+|\s+)*(?-xism:[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+(
?:\.[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+)*)(?-xism:(?-xism:
\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[
^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+)
)|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)
+|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:
(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((
?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\
x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*\[(?:\s*(?-xism:(?-x
ism:[^\[\]\\])|(?-xism:\\(?-xism:[^\x0A\x0D])))+)*\s*\](?-xi
sm:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:
\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(
?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+
)*\s*\)\s*)+|\s+)*)))>(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-
xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\
s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^
\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*))|(?-xism:(?-x
ism:(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^
()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*
(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D])
)|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*(?-xism:[^\x00-\x1F\x7F()
<>\[\]:;@\,.<DQ>\s]+(?:\.[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s
]+)*)(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+)
)|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism
:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\
s*\)\s*))+)*\s*\)\s*)+|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((
?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\
x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-x
ism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)
*<DQ>(?-xism:(?-xism:[^\\<DQ>])|(?-xism:\\(?-xism:[^\x0A\x0D
])))+<DQ>(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\
\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-
xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)
+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*))\@(?-xism:(?-xism:(?-xism:
(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(
?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[
^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\
s*\)\s*)+|\s+)*(?-xism:[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+
(?:\.[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+)*)(?-xism:(?-xism
:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:
[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+
))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*
)+|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism
:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\(
(?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A
\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*\[(?:\s*(?-xism:(?-
xism:[^\[\]\\])|(?-xism:\\(?-xism:[^\x0A\x0D])))+)*\s*\](?-x
ism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism
:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:
(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))
+)*\s*\)\s*)+|\s+)*))))(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?
>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:
\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0
D]))|)+)*\s*\)\s*))+)*\s*\)\s*)*)"
  .Replace("<DQ>", "\"")
  .Replace("\t", "")
  .Replace(" ", "")
  .Replace("\r", "")
  .Replace("\n", "");

private static Regex mailbox =
  new Regex(gibberish, RegexOptions.ExplicitCapture); 
11

Здесь PHP я использую. Я выбрал это решение в духе "ложных срабатываний лучше ложных негативов", как было объявлено другим комментатором здесь И в отношении сохранения времени ответа и загрузки сервера... на самом деле нет необходимости тратить ресурсы сервера на регулярное выражение, когда это избавит вас от самой простой ошибки пользователя. Вы всегда можете следить за этим, отправив тестовое письмо, если хотите.

function validateEmail($email) {
  return (bool) stripos($email,'@');
}
  • 1
    а) «Ресурсы ненужного сервера» бесконечно малы, но если вы так склонны, вы можете сделать это на стороне клиента с помощью JS. б) Что вам нужно, чтобы отправить регистрационное письмо, и пользователь вводит меня @ Forgotthedotcom? Ваше «решение» терпит неудачу, и вы теряете пользователя.
  • 0
    а) Полагаться на валидацию JS, которая потерпит неудачу при отключении JavaScript, тоже не лучшая идея (просто кстати)
11

Согласно официальному стандарту RFC 2822 действительное регулярное выражение электронной почты

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])

если вы хотите использовать его в Java, очень просто

import java.util.regex.*;

class regexSample 
{
   public static void main(String args[]) 
   {
      //Input the string for validation
      String email = "[email protected]";

      //Set the email pattern string
      Pattern p = Pattern.compile(" (?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"
              +"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")"
                     + "@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\]");

      //Match the given string with the pattern
      Matcher m = p.matcher(email);

      //check whether match is found 
      boolean matchFound = m.matches();

      if (matchFound)
        System.out.println("Valid Email Id.");
      else
        System.out.println("Invalid Email Id.");
   }
}
11

Стандарт RFC 5322:

Разрешает локальную часть локальной точки узловой точки, локальную часть с кавычками, устаревшую (смешанную точку-атом и котировку) локальную часть домена домена домена (IPv4, IPv6 и IPv4-адрес IPv6). литеральный домен и (вложенные) CFWS.

'/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD'

Стандарт RFC 5321:

Разрешает локальную часть локальной точки, локальную часть с кавычками, доменное имя домена и (IPv4, IPv6 и IPv4-адрес IPv6) доменный домен.

'/^(?!(?>"?(?>\\\[ -~]|[^"])"?){255,})(?!"?(?>\\\[ -~]|[^"]){65,}"?@)(?>([!#-\'*+\/-9=?^-~-]+)(?>\.(?1))*|"(?>[ !#-\[\]-~]|\\\[ -~])*")@(?!.*[^.]{64,})(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>\.(?2)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?3)){7}|(?!(?:.*[a-f0-9][:\]]){8,})((?3)(?>:(?3)){0,6})?::(?4)?))|(?>(?>IPv6:(?>(?3)(?>:(?3)){5}:|(?!(?:.*[a-f0-9]:){6,})(?5)?::(?>((?3)(?>:(?3)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>\.(?6)){3}))\])$/iD'

Basic:

Разрешает локальную часть домена и домена домена dot-atom (требуется, по меньшей мере, две метки имени домена с TLD, ограниченным 2-6 буквенными символами).

"/^(?!.{255,})(?!.{65,}@)([!#-'*+\/-9=?^-~-]+)(?>\.(?1))*@(?!.*[^.]{64,})(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?\.){1,126}[a-z]{2,6}$/iD"
  • 0
    Что это за дьявольский язык? Я вижу флаг /D , и вы заключили его в одинарные кавычки, но также использовали косую черту для разделения шаблона? Это не Perl, и это не может быть PCRE. Поэтому это PHP? Я считаю, что это единственные три, которые допускают рекурсию типа (?1) .
  • 0
    Это на PHP, который использует PCRE. Косая черта используется только для разделения специальных символов, таких как круглые скобки, квадратные скобки и, конечно, косая черта и одинарные кавычки. Флаг / D, если вы не знали, предназначен для предотвращения добавления новой строки в конец строки, что было бы разрешено в противном случае.
8
public bool ValidateEmail(string sEmail)
{
    if (sEmail == null)
    {
        return false;
    }

    int nFirstAT = sEmail.IndexOf('@');
    int nLastAT = sEmail.LastIndexOf('@');

    if ((nFirstAT > 0) && (nLastAT == nFirstAT) && (nFirstAT < (sEmail.Length - 1)))
    {
        return (Regex.IsMatch(sEmail, @"^[a-z|0-9|A-Z]*([_][a-z|0-9|A-Z]+)*([.][a-z|0-9|A-Z]+)*([.][a-z|0-9|A-Z]+)*(([_][a-z|0-9|A-Z]+)*)?@[a-z][a-z|0-9|A-Z]*\.([a-z][a-z|0-9|A-Z]*(\.[a-z][a-z|0-9|A-Z]*)?)$"));
    }
    else
    {
        return false;
    }
}
8

Странно, что вы "не можете" разрешить TLD с 4 символами. Вы запрещаете людям из .info и .name, а ограничение длины останавливается .travel и .museum, но да, они менее распространены, чем TLD с двумя символами и 3 доменов TLD.

Вы также должны вводить алфавиты в верхнем регистре. Системы электронной почты нормализуют локальную часть и часть домена.

Для вашего регулярного выражения части домена имя домена не может начинаться с '-' и не может заканчиваться на '-'. Черточка может находиться только между ними.

Если вы использовали библиотеку PEAR, проверьте их функцию почты (забыли точное имя/библиотеку). Вы можете проверить адрес электронной почты, вызвав одну функцию, и проверяет адрес электронной почты в соответствии с определением в RFC822.

  • 2
    @ Джозеф Йи: Разве RFC 822 немного не устарел?
7

Если вы согласны с принятием пустых значений (которые не являются недопустимыми для электронной почты) и работают с PHP 5.2+, я бы предложил:

static public function checkEmail($email, $ignore_empty = false) {
        if($ignore_empty && (is_null($email) || $email == ''))
                return true;
        return filter_var($email, FILTER_VALIDATE_EMAIL);
    }
6

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

"\A(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\Z";

Это регулярное выражение, которое я всегда использую в моем коде Asp.NET, и я очень доволен им.

используйте эту ссылку на сборку

using System.Text.RegularExpressions;

и попробуйте следующий код, поскольку он прост и выполняет вашу работу.

private bool IsValidEmail(string email) {
    bool isValid = false;
    const string pattern = @"\A(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\Z";

    isValid = email != "" && Regex.IsMatch(email, pattern);

    // an alternative of the above line is also given and commented
    //
    //if (email == "") {
    //    isValid = false;
    //} else {
    //    // address provided so use the IsMatch Method
    //    // of the Regular Expression object
    //    isValid = Regex.IsMatch(email, pattern);
    //}
    return isValid;
}

эта функция проверяет строку электронной почты. Если строка электронной почты имеет значение null, она возвращает false, если строка электронной почты не в правильном формате, она возвращает false. Он возвращает true только в том случае, если формат сообщения действителен.

  • 1
    Принимает ли этот код сообщения «Håkan.Söderström@malmö.se» или «Try @ example.Test. مثال.آزمایشی»?
  • 2
    Это для стандартных почтовых серверов со стандартными символами. В случае не английского языка нужно сделать свой собственный ReGex.
Показать ещё 1 комментарий
6

Я знаю, что этот вопрос касается RegEx, но, полагая, что 90% всех разработчиков, читающих эти решения, пытаются проверить адрес E-Mail в форме HTML, отображаемой в браузере.

Если это так, я бы предложил проверить новый элемент формы HTML5 <input type="email">:

HTML5:

 <input type="email" required />

CSS3:

 input:required {
      background-color: rgba(255,0,0,0.2);
 }

 input:focus:invalid { 
     box-shadow: 0 0 1em red;
     border-color: red;
 }

 input:focus:valid { 
     box-shadow: 0 0 1em green;
     border-color: green;
 }

http://jsfiddle.net/mYRe7/1

Это имеет несколько преимуществ:

  • Автоматическая проверка, нет необходимости в специальном решении: просто и легко реализовать
  • Нет JavaScript, никаких проблем, если JS отключен.
  • Никакой сервер не должен вычислять что-либо для этого
  • Пользователь имеет немедленную обратную связь
  • Старый браузер должен автоматически возвращаться к типу ввода "текст"
  • Мобильные браузеры могут отображать специализированную клавиатуру (@-Keyboard)
  • Обратная связь с проверкой формы очень проста с CSS3

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

также см.:

  • 0
    Другим недостатком является то, что это только на стороне клиента. Хорошо для обеспечения бесперебойного взаимодействия с пользователем, плохо для проверки данных.
  • 0
    Проблема с проверкой электронной почты по умолчанию состоит в том, что в ней много ложных срабатываний . Вам нужно будет использовать мой полный шаблон, чтобы исключить все ложные срабатывания, в то же время предотвращая проникновение ложных негативов. Этот шаблон можно добавить с помощью атрибута pattern . Смотрите мой пост для получения дополнительной информации.
6

Я использовал эту затронутую версию вашего регулярного выражения некоторое время, и это не оставило меня со слишком большим количеством сюрпризов. Я никогда не сталкивался с апострофом в электронном письме, но не подтвердил это. Он проверяет Jean+Franç[email protected] и 试@例子.测试.مثال.آزمایشی, но не странно злоупотребляет этими не буквенно-цифровыми символами [email protected].

(?!^[.+&'_-]*@.*$)(^[_\w\d+&'-]+(\.[_\w\d+&'-]*)*@[\w\d-]+(\.[\w\d-]+)*\.(([\d]{1,3})|([\w]{2,}))$)

Он поддерживает IP-адреса [email protected], но я не уточнил его достаточно, чтобы иметь дело с фиктивными диапазонами IP, такими как 999.999.999.1.

Он также поддерживает все TLD с тремя символами, которые останавливаются [email protected], которые, как мне кажется, пропустили оригинал. У меня есть были избиты, количество тлдов теперь превышает 3 символа.

Я знаю, что Acrosman отказался от своего регулярного выражения, но этот вкус живет.

5

Почти каждый RegEx, который я видел - в том числе некоторые, используемые Microsoft, не позволят пройти следующее действительное письмо: [email protected]

Просто у вас был настоящий клиент с адресом электронной почты в этом формате, который не мог разместить заказ.

Вот что я решил:

  • Минимальное регулярное выражение, которое не будет иметь ложных негативов. В качестве альтернативы используйте конструктор MailAddress с некоторыми дополнительными проверками (см. Ниже):
  • Проверка общих опечаток .cmo или .gmial.com и запрос подтверждения Are you sure this is your correct email address. It looks like there may be a mistake. Разрешить пользователю принимать то, что они набрали, если они уверены.
  • Обработка отскоков при отправке электронной почты и проверка их вручную для проверки очевидных ошибок.

        try
        {
            var email = new MailAddress(str);

            if (email.Host.EndsWith(".cmo"))
            {
                return EmailValidation.PossibleTypo;
            }

            if (!email.Host.EndsWith(".") && email.Host.Contains("."))
            {
                return EmailValidation.OK;
            }
        }
        catch
        {
            return EmailValidation.Invalid;
        }
  • 0
    Этот ответ вводит в заблуждение и не имеет отношения к вопросу. Разрешение пользователям вводить неправильный адрес электронной почты является бизнес-решением, вопрос заключается в том, чтобы проверить его с помощью регулярных выражений.
5

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

1) Сначала я проверяю с помощью самого основного регулярного выражения, которое просто проверяет, содержит ли адрес электронной почты только один знак @, и он не пуст до или после этого знака. например /^[^@\s]+@[^@\s]+$/

2a), если первый валидатор не проходит (и для большинства адресов он должен, хотя и не идеален), затем предупредить пользователя, что сообщение недействительно и не позволяет ему/ей продолжать вход

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

Иными словами, первая либеральная валидация - это просто снять очевидные ошибки, и она рассматривается как "ошибка". Люди печатают пустой адрес, адрес без знака @и т.д. Это следует рассматривать как ошибку. Второй является более строгим, но рассматривается как "предупреждение", и пользователю разрешено продолжать ввод, но он должен по крайней мере проверить, введен ли он в действительную запись. Ключевым моментом здесь является подход с ошибкой/предупреждением - ошибка, являющаяся чем-то, что не может быть действительным по электронной почте на основании 99.99%.

Из couse вы можете настроить то, что делает первое регулярное выражение более либеральным и вторым строгим.

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

5

Я не верю утверждению, сделанному bortzmeyer выше: "Грамматика (указанная в RFC 5322) слишком сложна для этого" (для обработки регулярным выражением).

Вот грамматика: (из http://tools.ietf.org/html/rfc5322#section-3.4.1)

addr-spec       =   local-part "@" domain
local-part      =   dot-atom / quoted-string / obs-local-part
domain          =   dot-atom / domain-literal / obs-domain
domain-literal  =   [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
dtext           =   %d33-90 /          ; Printable US-ASCII
                    %d94-126 /         ;  characters not including
                    obs-dtext          ;  "[", "]", or "\"

Предполагая, что dot-atom, кавычки, obs-local-part, obs-domain сами являются регулярными языками, это очень простая грамматика. Просто замените локальную часть и домен в производстве addr-spec с их соответствующими производными, и у вас есть обычный язык, который можно напрямую перевести в регулярное выражение.

  • 4
    Вам следует изучить CFWS, прежде чем начать делать предположения здесь. Это кошмар.
  • 0
    CFWS = (1 * (комментарий [FWS]) [FWS]) / FWS. Тем не менее, я не вижу правил, которые делают язык не регулярным. Это, конечно, сложно, но сложное регулярное выражение может справиться с этим.
Показать ещё 1 комментарий
4

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

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

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

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

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

4

Я не нашел ни одной сделки с доменным именем верхнего уровня, но это нужно учитывать.

Так что для меня следующий сработал -

[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2}AAA|AARP|ABB|ABBOTT|ABOGADO|AC|ACADEMY|ACCENTURE|ACCOUNTANT|ACCOUNTANTS|ACO|ACTIVE|ACTOR|AD|ADAC|ADS|ADULT|AE|AEG|AERO|AF|AFL|AG|AGENCY|AI|AIG|AIRFORCE|AIRTEL|AL|ALIBABA|ALIPAY|ALLFINANZ|ALSACE|AM|AMICA|AMSTERDAM|ANALYTICS|ANDROID|AO|APARTMENTS|APP|APPLE|AQ|AQUARELLE|AR|ARAMCO|ARCHI|ARMY|ARPA|ARTE|AS|ASIA|ASSOCIATES|AT|ATTORNEY|AU|AUCTION|AUDI|AUDIO|AUTHOR|AUTO|AUTOS|AW|AX|AXA|AZ|AZURE|BA|BAIDU|BAND|BANK|BAR|BARCELONA|BARCLAYCARD|BARCLAYS|BARGAINS|BAUHAUS|BAYERN|BB|BBC|BBVA|BCN|BD|BE|BEATS|BEER|BENTLEY|BERLIN|BEST|BET|BF|BG|BH|BHARTI|BI|BIBLE|BID|BIKE|BING|BINGO|BIO|BIZ|BJ|BLACK|BLACKFRIDAY|BLOOMBERG|BLUE|BM|BMS|BMW|BN|BNL|BNPPARIBAS|BO|BOATS|BOEHRINGER|BOM|BOND|BOO|BOOK|BOOTS|BOSCH|BOSTIK|BOT|BOUTIQUE|BR|BRADESCO|BRIDGESTONE|BROADWAY|BROKER|BROTHER|BRUSSELS|BS|BT|BUDAPEST|BUGATTI|BUILD|BUILDERS|BUSINESS|BUY|BUZZ|BV|BW|BY|BZ|BZH|CA|CAB|CAFE|CAL|CALL|CAMERA|CAMP|CANCERRESEARCH|CANON|CAPETOWN|CAPITAL|CAR|CARAVAN|CARDS|CARE|CAREER|CAREERS|CARS|CARTIER|CASA|CASH|CASINO|CAT|CATERING|CBA|CBN|CC|CD|CEB|CENTER|CEO|CERN|CF|CFA|CFD|CG|CH|CHANEL|CHANNEL|CHAT|CHEAP|CHLOE|CHRISTMAS|CHROME|CHURCH|CI|CIPRIANI|CIRCLE|CISCO|CITIC|CITY|CITYEATS|CK|CL|CLAIMS|CLEANING|CLICK|CLINIC|CLINIQUE|CLOTHING|CLOUD|CLUB|CLUBMED|CM|CN|CO|COACH|CODES|COFFEE|COLLEGE|COLOGNE|COM|COMMBANK|COMMUNITY|COMPANY|COMPARE|COMPUTER|COMSEC|CONDOS|CONSTRUCTION|CONSULTING|CONTACT|CONTRACTORS|COOKING|COOL|COOP|CORSICA|COUNTRY|COUPONS|COURSES|CR|CREDIT|CREDITCARD|CREDITUNION|CRICKET|CROWN|CRS|CRUISES|CSC|CU|CUISINELLA|CV|CW|CX|CY|CYMRU|CYOU|CZ|DABUR|DAD|DANCE|DATE|DATING|DATSUN|DAY|DCLK|DE|DEALER|DEALS|DEGREE|DELIVERY|DELL|DELTA|DEMOCRAT|DENTAL|DENTIST|DESI|DESIGN|DEV|DIAMONDS|DIET|DIGITAL|DIRECT|DIRECTORY|DISCOUNT|DJ|DK|DM|DNP|DO|DOCS|DOG|DOHA|DOMAINS|DOOSAN|DOWNLOAD|DRIVE|DUBAI|DURBAN|DVAG|DZ|EARTH|EAT|EC|EDEKA|EDU|EDUCATION|EE|EG|EMAIL|EMERCK|ENERGY|ENGINEER|ENGINEERING|ENTERPRISES|EPSON|EQUIPMENT|ER|ERNI|ES|ESQ|ESTATE|ET|EU|EUROVISION|EUS|EVENTS|EVERBANK|EXCHANGE|EXPERT|EXPOSED|EXPRESS|FAGE|FAIL|FAIRWINDS|FAITH|FAMILY|FAN|FANS|FARM|FASHION|FAST|FEEDBACK|FERRERO|FI|FILM|FINAL|FINANCE|FINANCIAL|FIRESTONE|FIRMDALE|FISH|FISHING|FIT|FITNESS|FJ|FK|FLIGHTS|FLORIST|FLOWERS|FLSMIDTH|FLY|FM|FO|FOO|FOOTBALL|FORD|FOREX|FORSALE|FORUM|FOUNDATION|FOX|FR|FRESENIUS|FRL|FROGANS|FUND|FURNITURE|FUTBOL|FYI|GA|GAL|GALLERY|GAME|GARDEN|GB|GBIZ|GD|GDN|GE|GEA|GENT|GENTING|GF|GG|GGEE|GH|GI|GIFT|GIFTS|GIVES|GIVING|GL|GLASS|GLE|GLOBAL|GLOBO|GM|GMAIL|GMO|GMX|GN|GOLD|GOLDPOINT|GOLF|GOO|GOOG|GOOGLE|GOP|GOT|GOV|GP|GQ|GR|GRAINGER|GRAPHICS|GRATIS|GREEN|GRIPE|GROUP|GS|GT|GU|GUCCI|GUGE|GUIDE|GUITARS|GURU|GW|GY|HAMBURG|HANGOUT|HAUS|HEALTH|HEALTHCARE|HELP|HELSINKI|HERE|HERMES|HIPHOP|HITACHI|HIV|HK|HM|HN|HOCKEY|HOLDINGS|HOLIDAY|HOMEDEPOT|HOMES|HONDA|HORSE|HOST|HOSTING|HOTELES|HOTMAIL|HOUSE|HOW|HR|HSBC|HT|HU|HYUNDAI|IBM|ICBC|ICE|ICU|ID|IE|IFM|IINET|IL|IM|IMMO|IMMOBILIEN|IN|INDUSTRIES|INFINITI|INFO|ING|INK|INSTITUTE|INSURANCE|INSURE|INT|INTERNATIONAL|INVESTMENTS|IO|IPIRANGA|IQ|IR|IRISH|IS|ISELECT|IST|ISTANBUL|IT|ITAU|IWC|JAGUAR|JAVA|JCB|JE|JETZT|JEWELRY|JLC|JLL|JM|JMP|JO|JOBS|JOBURG|JOT|JOY|JP|JPRS|JUEGOS|KAUFEN|KDDI|KE|KFH|KG|KH|KI|KIA|KIM|KINDER|KITCHEN|KIWI|KM|KN|KOELN|KOMATSU|KP|KPN|KR|KRD|KRED|KW|KY|KYOTO|KZ|LA|LACAIXA|LAMBORGHINI|LAMER|LANCASTER|LAND|LANDROVER|LANXESS|LASALLE|LAT|LATROBE|LAW|LAWYER|LB|LC|LDS|LEASE|LECLERC|LEGAL|LEXUS|LGBT|LI|LIAISON|LIDL|LIFE|LIFEINSURANCE|LIFESTYLE|LIGHTING|LIKE|LIMITED|LIMO|LINCOLN|LINDE|LINK|LIVE|LIVING|LIXIL|LK|LOAN|LOANS|LOL|LONDON|LOTTE|LOTTO|LOVE|LR|LS|LT|LTD|LTDA|LU|LUPIN|LUXE|LUXURY|LV|LY|MA|MADRID|MAIF|MAISON|MAKEUP|MAN|MANAGEMENT|MANGO|MARKET|MARKETING|MARKETS|MARRIOTT|MBA|MC|MD|ME|MED|MEDIA|MEET|MELBOURNE|MEME|MEMORIAL|MEN|MENU|MEO|MG|MH|MIAMI|MICROSOFT|MIL|MINI|MK|ML|MM|MMA|MN|MO|MOBI|MOBILY|MODA|MOE|MOI|MOM|MONASH|MONEY|MONTBLANC|MORMON|MORTGAGE|MOSCOW|MOTORCYCLES|MOV|MOVIE|MOVISTAR|MP|MQ|MR|MS|MT|MTN|MTPC|MTR|MU|MUSEUM|MUTUELLE|MV|MW|MX|MY|MZ|NA|NADEX|NAGOYA|NAME|NAVY|NC|NE|NEC|NET|NETBANK|NETWORK|NEUSTAR|NEW|NEWS|NEXUS|NF|NG|NGO|NHK|NI|NICO|NINJA|NISSAN|NL|NO|NOKIA|NORTON|NOWRUZ|NP|NR|NRA|NRW|NTT|NU|NYC|NZ|OBI|OFFICE|OKINAWA|OM|OMEGA|ONE|ONG|ONL|ONLINE|OOO|ORACLE|ORANGE|ORG|ORGANIC|ORIGINS|OSAKA|OTSUKA|OVH|PA|PAGE|PAMPEREDCHEF|PANERAI|PARIS|PARS|PARTNERS|PARTS|PARTY|PE|PET|PF|PG|PH|PHARMACY|PHILIPS|PHOTO|PHOTOGRAPHY|PHOTOS|PHYSIO|PIAGET|PICS|PICTET|PICTURES|PID|PIN|PING|PINK|PIZZA|PK|PL|PLACE|PLAY|PLAYSTATION|PLUMBING|PLUS|PM|PN|POHL|POKER|PORN|POST|PR|PRAXI|PRESS|PRO|PROD|PRODUCTIONS|PROF|PROMO|PROPERTIES|PROPERTY|PROTECTION|PS|PT|PUB|PW|PY|QA|QPON|QUEBEC|RACING|RE|READ|REALTOR|REALTY|RECIPES|RED|REDSTONE|REDUMBRELLA|REHAB|REISE|REISEN|REIT|REN|RENT|RENTALS|REPAIR|REPORT|REPUBLICAN|REST|RESTAURANT|REVIEW|REVIEWS|REXROTH|RICH|RICOH|RIO|RIP|RO|ROCHER|ROCKS|RODEO|ROOM|RS|RSVP|RU|RUHR|RUN|RW|RWE|RYUKYU|SA|SAARLAND|SAFE|SAFETY|SAKURA|SALE|SALON|SAMSUNG|SANDVIK|SANDVIKCOROMANT|SANOFI|SAP|SAPO|SARL|SAS|SAXO|SB|SBS|SC|SCA|SCB|SCHAEFFLER|SCHMIDT|SCHOLARSHIPS|SCHOOL|SCHULE|SCHWARZ|SCIENCE|SCOR|SCOT|SD|SE|SEAT|SECURITY|SEEK|SELECT|SENER|SERVICES|SEVEN|SEW|SEX|SEXY|SFR|SG|SH|SHARP|SHELL|SHIA|SHIKSHA|SHOES|SHOW|SHRIRAM|SI|SINGLES|SITE|SJ|SK|SKI|SKIN|SKY|SKYPE|SL|SM|SMILE|SN|SNCF|SO|SOCCER|SOCIAL|SOFTBANK|SOFTWARE|SOHU|SOLAR|SOLUTIONS|SONY|SOY|SPACE|SPIEGEL|SPREADBETTING|SR|SRL|ST|STADA|STAR|STARHUB|STATEFARM|STATOIL|STC|STCGROUP|STOCKHOLM|STORAGE|STUDIO|STUDY|STYLE|SU|SUCKS|SUPPLIES|SUPPLY|SUPPORT|SURF|SURGERY|SUZUKI|SV|SWATCH|SWISS|SX|SY|SYDNEY|SYMANTEC|SYSTEMS|SZ|TAB|TAIPEI|TAOBAO|TATAMOTORS|TATAR|TATTOO|TAX|TAXI|TC|TCI|TD|TEAM|TECH|TECHNOLOGY|TEL|TELEFONICA|TEMASEK|TENNIS|TF|TG|TH|THD|THEATER|THEATRE|TICKETS|TIENDA|TIFFANY|TIPS|TIRES|TIROL|TJ|TK|TL|TM|TMALL|TN|TO|TODAY|TOKYO|TOOLS|TOP|TORAY|TOSHIBA|TOURS|TOWN|TOYOTA|TOYS|TR|TRADE|TRADING|TRAINING|TRAVEL|TRAVELERS|TRAVELERSINSURANCE|TRUST|TRV|TT|TUBE|TUI|TUSHU|TV|TW|TZ|UA|UBS|UG|UK|UNIVERSITY|UNO|UOL|US|UY|UZ|VA|VACATIONS|VANA|VC|VE|VEGAS|VENTURES|VERISIGN|VERSICHERUNG|VET|VG|VI|VIAJES|VIDEO|VILLAS|VIN|VIP|VIRGIN|VISION|VISTA|VISTAPRINT|VIVA|VLAANDEREN|VN|VODKA|VOLKSWAGEN|VOTE|VOTING|VOTO|VOYAGE|VU|WALES|WALTER|WANG|WANGGOU|WATCH|WATCHES|WEATHER|WEBCAM|WEBER|WEBSITE|WED|WEDDING|WEIR|WF|WHOSWHO|WIEN|WIKI|WILLIAMHILL|WIN|WINDOWS|WINE|WME|WORK|WORKS|WORLD|WS|WTC|WTF|XBOX|XEROX|XIN|XN--11B4C3D|XN--1QQW23A|XN--30RR7Y|XN--3BST00M|XN--3DS443G|XN--3E0B707E|XN--3PXU8K|XN--42C2D9A|XN--45BRJ9C|XN--45Q11C|XN--4GBRIM|XN--55QW42G|XN--55QX5D|XN--6FRZ82G|XN--6QQ986B3XL|XN--80ADXHKS|XN--80AO21A|XN--80ASEHDB|XN--80ASWG|XN--90A3AC|XN--90AIS|XN--9DBQ2A|XN--9ET52U|XN--B4W605FERD|XN--C1AVG|XN--C2BR7G|XN--CG4BKI|XN--CLCHC0EA0B2G2A9GCD|XN--CZR694B|XN--CZRS0T|XN--CZRU2D|XN--D1ACJ3B|XN--D1ALF|XN--ECKVDTC9D|XN--EFVY88H|XN--ESTV75G|XN--FHBEI|XN--FIQ228C5HS|XN--FIQ64B|XN--FIQS8S|XN--FIQZ9S|XN--FJQ720A|XN--FLW351E|XN--FPCRJ9C3D|XN--FZC2C9E2C|XN--G2XX48C|XN--GECRJ9C|XN--H2BRJ9C|XN--HXT814E|XN--I1B6B1A6A2E|XN--IMR513N|XN--IO0A7I|XN--J1AEF|XN--J1AMH|XN--J6W193G|XN--JLQ61U9W7B|XN--KCRX77D1X4A|XN--KPRW13D|XN--KPRY57D|XN--KPU716F|XN--KPUT3I|XN--L1ACC|XN--LGBBAT1AD8J|XN--MGB9AWBF|XN--MGBA3A3EJT|XN--MGBA3A4F16A|XN--MGBAAM7A8H|XN--MGBAB2BD|XN--MGBAYH7GPA|XN--MGBB9FBPOB|XN--MGBBH1A71E|XN--MGBC0A9AZCG|XN--MGBERP4A5D4AR|XN--MGBPL2FH|XN--MGBT3DHD|XN--MGBTX2B|XN--MGBX4CD0AB|XN--MK1BU44C|XN--MXTQ1M|XN--NGBC5AZD|XN--NGBE9E0A|XN--NODE|XN--NQV7F|XN--NQV7FS00EMA|XN--NYQY26A|XN--O3CW4H|XN--OGBPF8FL|XN--P1ACF|XN--P1AI|XN--PBT977C|XN--PGBS0DH|XN--PSSY2U|XN--Q9JYB4C|XN--QCKA1PMC|XN--QXAM|XN--RHQV96G|XN--S9BRJ9C|XN--SES554G|XN--T60B56A|XN--TCKWE|XN--UNUP4Y|XN--VERMGENSBERATER-CTB|XN--VERMGENSBERATUNG-PWB|XN--VHQUV|XN--VUQ861B|XN--WGBH1C|XN--WGBL6A|XN--XHQ521B|XN--XKC2AL3HYE2A|XN--XKC2DL3A5EE0H|XN--Y9A3AQ|XN--YFRO4I67O|XN--YGBI2AMMX|XN--ZFR164B|XPERIA|XXX|XYZ|YACHTS|YAMAXUN|YANDEX|YE|YODOBASHI|YOGA|YOKOHAMA|YOUTUBE|YT|ZA|ZARA|ZERO|ZIP|ZM|ZONE|ZUERICH|ZW)\b

Это легко отбрасывает электронные письма, такие как [email protected], [email protected] и т.д.

Доменное имя может быть дополнительно отредактировано, если необходимо, например. конкретный домен страны и т.д.

  • 0
    Как уже указывалось в нескольких комментариях к другим ответам, список действительных TLD быстро растет. Ваш «двухбуквенный ccTLD или один из big-6, info, mobi и т. Д.» Был бы разумным пять лет назад, но больше не работает надежно.
  • 0
    Даже во время первоначального написания, это было недействительно несколькими сотнями TLD. На данный момент вы упускаете чуть менее 1200 возможностей (и растете с довольно регулярной скоростью). Текущий список действительных доменов: data.iana.org/TLD/tlds-alpha-by-domain.txt
4

Для 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

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

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

  • 0
    «более актуальная дискуссия» с 2011 года?
4

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

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

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

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

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

  • 0
    Не разрешает "John Smith"@example.com .
  • 0
    Правда, но когда это действительно нужно?
Показать ещё 2 комментария
4

AS за мое понимание, наиболее вероятное будет охватывать..

/^([a-z0-9_-]+)(@[a-z0-9-]+)(\.[a-z]+|\.[a-z]+\.[a-z]+)?$/is
  • 0
    Улучшение / предложение всегда действуют как катализатор, так что будьте катализированы и катализировать меня тоже.
  • 0
    Пользователи Gmail часто используют. и + в их нике электронной почты, и некоторые комментарии на этой странице упоминают 'и!.
4

это одно из регулярных выражений для электронной почты

^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$
4

Мы использовали http://www.aspnetmx.com/ со степенью успеха в течение нескольких лет. Вы можете выбрать уровень, который хотите проверить (например, проверку синтаксиса, проверку домена, записей mx или фактического сообщения электронной почты).

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

3

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

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

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

Я нашел хорошую статью, в которой говорится, что лучший способ проверить адрес электронной почты - это выражение регулярных выражений: /.+@.+\..+/i

  • 2
    Он не соответствует действительным адресам, таким как: me@localhost
  • 0
    Он также соответствует недействительным адресам, таким как john doe @ his domain.com.
3

Регулярные выражения, опубликованные в этом потоке, теперь устарели из-за появления новых общих доменов верхнего уровня (gTLD) (например,.london,.basketball,. 通 販). Чтобы проверить адрес электронной почты, есть два ответа (это будет иметь отношение к подавляющему большинству).

  • Как говорится в главном ответе - не используйте регулярное выражение, просто подтвердите его, отправив электронное письмо по адресу (Исключить недопустимые адреса)
  • Используйте очень общее регулярное выражение, чтобы убедиться, что они используют структуру электронной почты {something}@{something}.{something}. Нет смысла искать подробное регулярное выражение, потому что вы не поймаете их всех, и через несколько лет будет новая партия, и вам снова придется обновлять свое регулярное выражение.

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

(.+)@(.+){2,}\.(.+){2,}
3

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

[\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) являются необязательными, но также могут повторяться несколько раз. Я думаю, что это проверяет все допустимые адреса электронной почты, но блокирует потенциальную недействительность без использования сложного регулярного выражения, которое в большинстве случаев не понадобится.

Обратите внимание, что это позволит [email protected], но это компромисс для его простоты.

  • 0
    Спасибо! Это сработало для меня. Вот проверенная экранированная версия C / C ++, используемая с Qt5: QRegExp rx ("[\\ w + -] + (?: \\. [\\ w + -] +) * @ [\\ w + -] + (?: \\ [\\ W + -] +) * (:.?. \\ [A-Za-Z] {2}) ");
3

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

3

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

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

no [email protected]

no [email protected]

/^([a-z0-9\+\._\/&!][-a-z0-9\+\._\/&!]*)@(([a-z0-9][-a-z0-9]*\.)([-a-z0-9]+\.)*[a-z]{2,})$/i
3

Никто не упоминал проблему локализации (i18), что делать, если у вас есть клиенты из разных стран мира? Затем вам нужно будет подклассифицировать ваше регулярное выражение для каждой страны/области, что я видел, как разработчики заканчивали создание большого словаря/конфига. Обнаружение настроек языка браузера пользователей может быть хорошей отправной точкой.

2

Java Mail API делает магию для нас.

try
    {
     InternetAddress internetAddress = new InternetAddress(email);
     internetAddress.validate();
     return true;
    }
    catch(Exception ex)
    {
        return false;
    }

Я получил это от здесь

  • 1
    Java Mail API - это необязательный пакет для использования с платформой Java SE, который включен в платформу Java EE.
2

Пришлось упомянуть, что почти был добавлен новый домен "yandex". Возможные электронные письма: [email protected]. А также поддерживаются заглавные буквы, поэтому немного измененная версия решения acrosman:

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

Согласно RFC 2821 и RFC 2822, локальная часть адресов электронной почты может использовать любой из этих символов ASCII:

  1. Письма с верхним и нижним регистрами
  2. Цифры от 0 до 9
  3. Символы,! # $% & '* + -/=? ^ _' {|} ~
  4. Персонаж "." при условии, что это не первый или последний символ в локальной части.

Матчи:

Non-Похожее:

Для RFC 2821, 2822 Compliant вы можете использовать:

^((([!#$%&'*+\-/=?^_'{|}~\w])|([!#$%&'*+\-/=?^_'{|}~\w][!#$%&'*+\-/=?^_'{|}~\.\w]{0,}[!#$%&'*+\-/=?^_'{|}~\w]))[@]\w+([-.]\w+)*\.\w+([-.]\w+)*)$

Электронная почта - RFC 2821, 2822

1

Приятно, я преобразовал код в java для соответствия компилятору

String pattern ="(?:[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?|\\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-zA-Z0-9-]*[a-zA-Z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])";
1

Ниже приведено регулярное выражение для проверки адреса электронной почты

^.+@\w+(\.\w+)+$
1

Как уже упоминалось, вы не можете проверить письмо с регулярным выражением. Однако здесь то, что мы в настоящее время используем, чтобы убедиться, что пользовательский ввод не является полностью фиктивным (забыв о TLD и т.д.).

Это регулярное выражение позволит домены IDN и специальные символы (например, Umlauts) до и после знака @.

/^[\w.+-_]+@[^.][\w.-]*\.[\w-]{2,63}$/iu
1

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

  • Если ваше приложение включает в себя что-то очень техническое (или что-то внутреннее для организаций), возможно, вам нужно поддерживать IP-адреса вместо доменных имен или комментарии в "локальной" части адреса электронной почты.
  • Если ваше приложение является многонациональным, я бы хотел сосредоточиться на поддержке Unicode/UTF8.

Ведущий ответ на ваш вопрос в настоящее время ссылается на "полностью RFC-822-совместимое регулярное выражение". Однако, несмотря на сложность этого регулярного выражения и его предполагаемое внимание к деталям в правилах RFC, он полностью терпит неудачу, когда дело доходит до поддержки Unicode.

В регулярном выражении, которое я написал для большинства моих приложений, основное внимание уделяется поддержке Unicode, а также достаточно хорошей общей приверженности стандартам RFC:

/^(?!\.)((?!.*\.{2})[a-zA-Z0-9\u0080-\u00FF\u0100-\u017F\u0180-\u024F\u0250-\u02AF\u0300-\u036F\u0370-\u03FF\u0400-\u04FF\u0500-\u052F\u0530-\u058F\u0590-\u05FF\u0600-\u06FF\u0700-\u074F\u0750-\u077F\u0780-\u07BF\u07C0-\u07FF\u0900-\u097F\u0980-\u09FF\u0A00-\u0A7F\u0A80-\u0AFF\u0B00-\u0B7F\u0B80-\u0BFF\u0C00-\u0C7F\u0C80-\u0CFF\u0D00-\u0D7F\u0D80-\u0DFF\u0E00-\u0E7F\u0E80-\u0EFF\u0F00-\u0FFF\u1000-\u109F\u10A0-\u10FF\u1100-\u11FF\u1200-\u137F\u1380-\u139F\u13A0-\u13FF\u1400-\u167F\u1680-\u169F\u16A0-\u16FF\u1700-\u171F\u1720-\u173F\u1740-\u175F\u1760-\u177F\u1780-\u17FF\u1800-\u18AF\u1900-\u194F\u1950-\u197F\u1980-\u19DF\u19E0-\u19FF\u1A00-\u1A1F\u1B00-\u1B7F\u1D00-\u1D7F\u1D80-\u1DBF\u1DC0-\u1DFF\u1E00-\u1EFF\u1F00-\u1FFFu20D0-\u20FF\u2100-\u214F\u2C00-\u2C5F\u2C60-\u2C7F\u2C80-\u2CFF\u2D00-\u2D2F\u2D30-\u2D7F\u2D80-\u2DDF\u2F00-\u2FDF\u2FF0-\u2FFF\u3040-\u309F\u30A0-\u30FF\u3100-\u312F\u3130-\u318F\u3190-\u319F\u31C0-\u31EF\u31F0-\u31FF\u3200-\u32FF\u3300-\u33FF\u3400-\u4DBF\u4DC0-\u4DFF\u4E00-\u9FFF\uA000-\uA48F\uA490-\uA4CF\uA700-\uA71F\uA800-\uA82F\uA840-\uA87F\uAC00-\uD7AF\uF900-\uFAFF\.!#$%&'*+-/=?^_`{|}~\-\d]+)@(?!\.)([a-zA-Z0-9\u0080-\u00FF\u0100-\u017F\u0180-\u024F\u0250-\u02AF\u0300-\u036F\u0370-\u03FF\u0400-\u04FF\u0500-\u052F\u0530-\u058F\u0590-\u05FF\u0600-\u06FF\u0700-\u074F\u0750-\u077F\u0780-\u07BF\u07C0-\u07FF\u0900-\u097F\u0980-\u09FF\u0A00-\u0A7F\u0A80-\u0AFF\u0B00-\u0B7F\u0B80-\u0BFF\u0C00-\u0C7F\u0C80-\u0CFF\u0D00-\u0D7F\u0D80-\u0DFF\u0E00-\u0E7F\u0E80-\u0EFF\u0F00-\u0FFF\u1000-\u109F\u10A0-\u10FF\u1100-\u11FF\u1200-\u137F\u1380-\u139F\u13A0-\u13FF\u1400-\u167F\u1680-\u169F\u16A0-\u16FF\u1700-\u171F\u1720-\u173F\u1740-\u175F\u1760-\u177F\u1780-\u17FF\u1800-\u18AF\u1900-\u194F\u1950-\u197F\u1980-\u19DF\u19E0-\u19FF\u1A00-\u1A1F\u1B00-\u1B7F\u1D00-\u1D7F\u1D80-\u1DBF\u1DC0-\u1DFF\u1E00-\u1EFF\u1F00-\u1FFF\u20D0-\u20FF\u2100-\u214F\u2C00-\u2C5F\u2C60-\u2C7F\u2C80-\u2CFF\u2D00-\u2D2F\u2D30-\u2D7F\u2D80-\u2DDF\u2F00-\u2FDF\u2FF0-\u2FFF\u3040-\u309F\u30A0-\u30FF\u3100-\u312F\u3130-\u318F\u3190-\u319F\u31C0-\u31EF\u31F0-\u31FF\u3200-\u32FF\u3300-\u33FF\u3400-\u4DBF\u4DC0-\u4DFF\u4E00-\u9FFF\uA000-\uA48F\uA490-\uA4CF\uA700-\uA71F\uA800-\uA82F\uA840-\uA87F\uAC00-\uD7AF\uF900-\uFAFF\-\.\d]+)((\.([a-zA-Z\u0080-\u00FF\u0100-\u017F\u0180-\u024F\u0250-\u02AF\u0300-\u036F\u0370-\u03FF\u0400-\u04FF\u0500-\u052F\u0530-\u058F\u0590-\u05FF\u0600-\u06FF\u0700-\u074F\u0750-\u077F\u0780-\u07BF\u07C0-\u07FF\u0900-\u097F\u0980-\u09FF\u0A00-\u0A7F\u0A80-\u0AFF\u0B00-\u0B7F\u0B80-\u0BFF\u0C00-\u0C7F\u0C80-\u0CFF\u0D00-\u0D7F\u0D80-\u0DFF\u0E00-\u0E7F\u0E80-\u0EFF\u0F00-\u0FFF\u1000-\u109F\u10A0-\u10FF\u1100-\u11FF\u1200-\u137F\u1380-\u139F\u13A0-\u13FF\u1400-\u167F\u1680-\u169F\u16A0-\u16FF\u1700-\u171F\u1720-\u173F\u1740-\u175F\u1760-\u177F\u1780-\u17FF\u1800-\u18AF\u1900-\u194F\u1950-\u197F\u1980-\u19DF\u19E0-\u19FF\u1A00-\u1A1F\u1B00-\u1B7F\u1D00-\u1D7F\u1D80-\u1DBF\u1DC0-\u1DFF\u1E00-\u1EFF\u1F00-\u1FFF\u20D0-\u20FF\u2100-\u214F\u2C00-\u2C5F\u2C60-\u2C7F\u2C80-\u2CFF\u2D00-\u2D2F\u2D30-\u2D7F\u2D80-\u2DDF\u2F00-\u2FDF\u2FF0-\u2FFF\u3040-\u309F\u30A0-\u30FF\u3100-\u312F\u3130-\u318F\u3190-\u319F\u31C0-\u31EF\u31F0-\u31FF\u3200-\u32FF\u3300-\u33FF\u3400-\u4DBF\u4DC0-\u4DFF\u4E00-\u9FFF\uA000-\uA48F\uA490-\uA4CF\uA700-\uA71F\uA800-\uA82F\uA840-\uA87F\uAC00-\uD7AF\uF900-\uFAFF]){2,63})+)$/i

Я не буду копировать полные ответы, поэтому я просто свяжу это с похожим ответом, представленным здесь: Как проверить электронную почту в формате unicode?

Существует также живая демонстрация для регулярного выражения выше: http://jsfiddle.net/aossikine/qCLVH/3/

1

Регулярное выражение, которое делает именно то, что говорят стандарты, в соответствии с тем, что я видел о них, заключается в следующем:

/^(?!(^[.-].*|.*[.-]@|.*\.{2,}.*)|^.{254}.+@)([a-z\xC0-\xFF0-9!#$%&'*+\/=?^_`{|}~.-]+@)(?!.{253}.+$)((?!-.*|.*-\.)([a-z0-9-]{1,63}\.)+[a-z]{2,63}|(([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9])\.){3}([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9]))$/gim

Демо/ Анализ Debuggex (интерактивный)

Разделить:

^(?!(^[.-].*|.*[.-]@|.*\.{2,}.*)|^.{254}.+@)
([a-z\xC0-\xFF0-9!#$%&'*+\/=?^_`{|}~.-]+@)
(?!.{253}.+$)
(
    (?!-.*|.*-\.)
    ([a-z0-9-]{1,63}\.)+
    [a-z]{2,63}
    |
    (([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9])\.){3}
    ([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9])
)$

Анализ:

(?!(^[.-].*|.*[.-]@|.*\.{2,}.*)|^.{254}.+@)

Отрицательный взгляд на адрес, начинающийся с ., заканчивающийся на один, имеющий .. в нем или превышающий максимальная длина 254 символа


([a-z\xC0-\xFF0-9!#$%&'*+\/=?^_`{|}~.-]+@)

сопоставление 1 или более разрешенных символов с отрицательным обращением к нему


(?!.{253}.+$)

Отрицательный просмотр части имени домена, ограничивающий его всего 253 символа


(?!-.*|.*-\.)

Отрицательный прогноз для каждого из доменных имен, которые не позволяют начинать или заканчивать с .


([a-z0-9-]{1,63}\.)+

простое совпадение групп для разрешенных символов в доменном имени, которые ограничены 63 символами каждый


[a-zA-Z]{2,63}

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


(([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9])\.){3}
([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9])

альтернатива для доменных имен: это соответствует первым 3 номерам в IP-адресе с . позади него, а затем четвертое число в IP-адресе без . позади него.

1

У меня было похожее желание: нужно быстро проверить синтаксис адресов электронной почты, не переходя за борт (ответ Mail::RFC822::Address, который является явно правильным) для утилита отправки электронной почты. Я пошел с этим (Im a POSIX RE человек, поэтому я обычно не использую \d и такой от PCRE, поскольку они делают вещи менее разборчивыми для меня):

preg_match("_^[-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*@[0-9A-Za-z]([-0-9A-Za-z]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([-0-9A-Za-z]{0,61}[0-9A-Za-z])?)*\$_", $adr)

Это RFC-исправление, но явно исключает устаревшие формы, а также прямые IP-адреса (IP и Legacy IP), которые кто-то из целевой группы этой утилиты (в основном: люди, которые беспокоят нас в #sendmail на IRC) обычно не нужны или не нужны.

IDN (интернационализированные доменные имена) явно не входят в сферу электронной почты: адреса, такие как "foo@cäcilienchor-bonn.de", должны быть написаны "[email protected]" на проводе вместо (это включает в себя mailto: ссылки в HTML и такое удовольствие), только GUI разрешено отображать (и принимать затем конвертировать) такие имена в (и из) пользователя.

1

I нашел регулярное выражение, которое соответствует RFC 2822. Предыдущий стандарт для RFC 5322. Это регулярное выражение, похоже, работает достаточно хорошо и будет охватывать большинство случаев, однако, если RFC 5322 станет стандартом, могут быть некоторые отверстия, которые должны быть подключены.

^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$

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

[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?

Я заметил, что это чувствительно к регистру, поэтому я фактически внес изменения в эту посадку.

^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$
1

Всемирная самая популярная платформа для ведения блога WordPress использует эту функцию для проверки адреса электронной почты.

Но они делают это с несколькими шагами.

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

Вот функция.

/**
 * Verifies that an email is valid.
 *
 * Does not grok i18n domains. Not RFC compliant.
 *
 * @since 0.71
 *
 * @param string $email Email address to verify.
 * @param boolean $deprecated Deprecated.
 * @return string|bool Either false or the valid email address.
 */
function is_email( $email, $deprecated = false ) {
    if ( ! empty( $deprecated ) )
        _deprecated_argument( __FUNCTION__, '3.0' );

    // Test for the minimum length the email can be
    if ( strlen( $email ) < 3 ) {
        return apply_filters( 'is_email', false, $email, 'email_too_short' );
    }

    // Test for an @ character after the first position
    if ( strpos( $email, '@', 1 ) === false ) {
        return apply_filters( 'is_email', false, $email, 'email_no_at' );
    }

    // Split out the local and domain parts
    list( $local, $domain ) = explode( '@', $email, 2 );

    // LOCAL PART
    // Test for invalid characters
    if ( !preg_match( '/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]+$/', $local ) ) {
        return apply_filters( 'is_email', false, $email, 'local_invalid_chars' );
    }

    // DOMAIN PART
    // Test for sequences of periods
    if ( preg_match( '/\.{2,}/', $domain ) ) {
        return apply_filters( 'is_email', false, $email, 'domain_period_sequence' );
    }

    // Test for leading and trailing periods and whitespace
    if ( trim( $domain, " \t\n\r\0\x0B." ) !== $domain ) {
        return apply_filters( 'is_email', false, $email, 'domain_period_limits' );
    }

    // Split the domain into subs
    $subs = explode( '.', $domain );

    // Assume the domain will have at least two subs
    if ( 2 > count( $subs ) ) {
        return apply_filters( 'is_email', false, $email, 'domain_no_periods' );
    }

    // Loop through each sub
    foreach ( $subs as $sub ) {
        // Test for leading and trailing hyphens and whitespace
        if ( trim( $sub, " \t\n\r\0\x0B-" ) !== $sub ) {
            return apply_filters( 'is_email', false, $email, 'sub_hyphen_limits' );
        }

        // Test for invalid characters
        if ( !preg_match('/^[a-z0-9-]+$/i', $sub ) ) {
            return apply_filters( 'is_email', false, $email, 'sub_invalid_chars' );
        }
    }

    // Congratulations your email made it!
    return apply_filters( 'is_email', $email, $email, null );
}
0

Мне не нравится держать вещи сложными и трудными для понимания.

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

^([A-z0-9_.]{2,})([@]{1})([A-z]{1,})([.]{1})([A-z.]{1,})*$

Вот как это работает

  1. минимум 2 буквы, включая алфавиты, цифры, подчеркивание и точку.
  2. Затем один @ в целом по электронной почте.
  3. По крайней мере один алфавит
  4. Одна точка
  5. Наконец, за ним следуют другие алфавиты и точка

пример

[email protected]
[email protected]
[email protected]
0
if(!preg_match("/([\w\-]+\@[\w\-]+\.[\w\-]+)/",$email)){
// email is invalid
} else {
// email is valid
}
0
var emailRegex = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;

// Example validation
if(emailRegex.test(email_value) == false) {
alert("Invalid email");
}
0

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

^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$

Для PHP

  function checkEmailValidation($email)
  {         
       $expression='/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/';
        if(preg_match($expression, $email))
        {
            return true;
        }else
        {
            return false;
        }
   }

Для Javascript

 function checkEmailValidation(email)
  {         
        var pattern='/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/';
        if(pattern.test(email))
        {
            return true;
        }else
        {
            return false;
        }
   }
  • 1
    if(preg_match($expression, $email)) { return true; } else { return false; } можно упростить до return (bool) preg_match($expression, $email);
0

Действительный RegEx согласно w3 org и wikipedia

[A-Z0-9a-z.!#$%&'*+-/=?^_`{|}~]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}

например.! # $% & Амп;?. * + -/= ^ _ `{|} [email protected]

  • 0
    mail@example проходит, допустимо, но скорее всего не очень полезно
  • 0
    Это регулярное выражение неверно и не рекомендуется на W3.org.
Показать ещё 2 комментария
0
^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.(([0-9]{1,3})|([a-zA-Z]{2,3})|(aero|coop|info|museum|name))$

Это соответствует 99,99% адресов электронной почты, включая некоторые из новых расширений верхнего уровня домена, такие как информация, музей, имя и т.д. Он также позволяет связать электронные письма напрямую с IP-адресами.

-1

Кто сказал, что нет хорошего регулярного выражения для проверки подлинности электронной почты?

Вот он, и насколько я знаю самое эффективное и кратчайшее регулярное выражение:)

Это лучший вариант для ребята и его официального регулярного выражения Microsoft, которое я получил от Visual Studio 2013 Ultimate.

\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*

Итак, проверьте это.

Я хочу доказать, что Microsoft ошибается, и, следовательно, докажу, что я ошибаюсь:)

-2

Вам не нужно проверять каждую символическую edgecase. Будь проще. Просто найдите символ "AT" и правильно сформируйте электронное письмо и закончите работу с действующим доменом.

Пример:

/^ [^.\@] + (. [^.\@]) *\@[^.\@] + (. [^.\@] +) + $/

Это будет захватывать: [email protected] и т.д... но терпеть неудачу myemail.anyAmountOfDotAndWord @ попробуйте.

-2
if(empty($emailId)){
    $er = "Please enter E-mail";
}else if(!preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/i", $emailId)){
    $er="Invalid Email. Address";
}
-2

Я использовал

/^[_A-Za-z0-9-]+(\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(\.[A-Za-z]{2,4})$/

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

-3

Короткий и простой синтаксис регулярного выражения

"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|" + @"([-a-z0-9!#$%&'*+/=?^_'{|}~]|(?<!\.)\.)*)(?<!\.)" + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$"

Используйте в своем коде для проверки электронной почты.

-3

Я использую этот

^[_\w-]+[\._\w-]*@[\w\.]+[a-z]{2,4}$
-8

Я поклонник простого, но очень эффективного:

([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})
-11

Чтобы проверить адрес электронной почты с помощью JavaScript, более удобно и эффективно использовать эту функцию (в соответствии с w3school):

function validateEmail()
{
var x=document.f.email.value;
var atpos=x.indexOf("@");
var dotpos=x.lastIndexOf(".");
if (atpos<1 || dotpos<atpos+2 || dotpos+2>=x.length)
  {
  alert("Not a valid e-mail address");
  return false;
  }
}

Я использую его, и он идеален. Я надеюсь быть полезным.

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню