Как проверить адрес электронной почты в JavaScript

4381

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

pix0r
источник
60
пожалуйста, поймите это правильно, слишком многим веб-сайтам не нравится мой адрес электронной почты "firstName@secondName.name", не все домены верхнего уровня заканчиваются на 2 или 3 буквы.
Ян Рингроз
41
Любая поддержка использования проверок регулярных выражений для электронных писем я против 100%. Мне надоело, что мой адрес электронной почты "foo+bar@gmail.com" недействителен. Лучший вариант - попросить пользователя ввести свою электронную почту дважды, и если вы ДОЛЖНЫ использовать проверку на регулярные выражения, то скажите пользователю, что его адрес электронной почты не является действительным, и спросите, уверены ли они, что он его набрал. правильно. Даже зайдите так далеко, чтобы указать, ЧТО не проверялось в проверке регулярных выражений, но НЕ мешайте им отправлять форму.
Soundfx4
17
@ Soundfx4: это должен быть ответ, принятый как таковой. Проверка правильности адреса - это глупая вещь - лучший способ разочаровать клиентов. Я прошу адрес наберется дважды и намек , что есть некоторые возможные проблемы (отсутствует @, ;comи т.д.) , и пусть пользователь исправить их , если они хотят (и принимать то , что они посылают меня)
WOJ
4
Я полностью согласен с ответом WoJ. Формат действующего адреса электронной почты слишком сложен, чтобы его можно было проверить с помощью простого регулярного выражения. Единственный способ убедиться, что адрес действителен, это попробовать его.
Николь

Ответы:

4951

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

function validateEmail(email) {
    const re = /^(([^<>()\[\]\\.,;:\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,}))$/;
    return re.test(String(email).toLowerCase());
}

Вот пример регулярного выражения, принимающего Unicode:

const re = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;

Но имейте в виду, что не следует полагаться только на валидацию JavaScript. JavaScript можно легко отключить. Это должно быть проверено и на стороне сервера.

Вот пример вышесказанного в действии:

function validateEmail(email) {
  const re = /^(([^<>()[\]\\.,;:\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,}))$/;
  return re.test(email);
}

function validate() {
  const $result = $("#result");
  const email = $("#email").val();
  $result.text("");

  if (validateEmail(email)) {
    $result.text(email + " is valid :)");
    $result.css("color", "green");
  } else {
    $result.text(email + " is not valid :(");
    $result.css("color", "red");
  }
  return false;
}

$("#validate").on("click", validate);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<form>
  <p>Enter an email address:</p>
  <input id='email'>
  <button type='submit' id='validate'>Validate!</button>
</form>

<h2 id='result'></h2>

рневий
источник
576
Это регулярное выражение исключает действительные, используемые электронные письма. Не используйте. Google для "RFC822" или "RFC2822", чтобы получить правильное регулярное выражение.
Рэндал Шварц
42
Это даже не принимает примеры в RFC 822. В некоторых простых случаях это не соответствует a \ @ b @ c.com, a(b)@c.com. Смотрите RFC для получения дополнительной информации. Вот регулярное выражение, которое не отклоняет допустимые адреса [^ @] + @ [^ @] + \. [^ @] + И защищает от распространенных ошибок.
Vroo
126
@ GoodPerson Я только что попытался написать электронное письмо n @ ai, чтобы сказать ему / ей, что у них есть классный адрес электронной почты. Но, увы, Gmail не позволил бы мне. Я подозреваю, что у кого бы то ни было, есть большие проблемы в общении с другими по электронной почте, чем просто проверка JavaScript моего сайта! Но спасибо, что приняли вызов.
Бен Робертс
26
Это решение кажется хорошим для большинства носителей английского языка, но оно не проходит тестирование в Турции (см. Джоэл Спольски). Допускается большинство писем в Юникоде, и, например, в Аргентине такие адреса, как «ñoñó1234@server.com», вполне нормальны. joelonsoftware.com/articles/Unicode.html
oligofren
139
Вы не можете проверить адреса электронной почты, точка. Единственный, кто может подтвердить адрес электронной почты, является поставщиком адреса электронной почты. Например, в этом ответе говорится, что все эти адреса электронной почты %2@gmail.com, "%2"@gmail.com, "a..b"@gmail.com, "a_b"@gmail.com, _@gmail.com, 1@gmail.com , 1_example@something.gmail.comдействительны, но Gmail никогда не разрешит использование этих адресов электронной почты. Вы должны сделать это, приняв адрес электронной почты и отправив сообщение на этот адрес электронной почты с кодом / ссылкой, которую пользователь должен посетить, чтобы подтвердить действительность.
Кевин Феган
830

Я немного изменил ответ Джеймона для людей, которым нужна действительно простая проверка в виде:

anystring@anystring.anystring

Регулярное выражение:

/\S+@\S+\.\S+/

Пример функции JavaScript:

function validateEmail(email) 
    {
        var re = /\S+@\S+\.\S+/;
        return re.test(email);
    }
    
console.log(validateEmail('anystring@anystring.anystring'));

C. Lee
источник
69
Вы можете реализовать что-то в 20 раз дольше, что может вызвать проблемы у нескольких пользователей и может оказаться недействительным в будущем, или вы можете взять версию ImmortalFirefly, чтобы убедиться, что они хотя бы приложат усилия, чтобы это выглядело реальным. В зависимости от вашего приложения, это может привести к тому, что кто-то разозлится из-за того, что вы не принимаете их нетрадиционную электронную почту, а не кого-то, кто вызывает проблемы, вводя адреса электронной почты, которые на самом деле не существуют (что они могут сделать в любом случае, введя 100% действительный адрес электронной почты RFC2822, но с использованием незарегистрированного имени пользователя или домена). Upvoted!
user83358
82
@ImmortalFirefly, приведенное вами регулярное выражение будет фактически соответствовать name@again@example.com. Попробуйте вставить свою строку в консоль JavaScript. Я полагаю, что ваше намерение состояло в том, чтобы соответствовать только всему тексту, что потребовало бы начала текстовых операторов '^' и конца текста '$'. Тот, который я использую/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test('name@again@example.com')
OregonTrail
8
На основании этой проверки это письмо действительно: check @ this..com
Ehsan
4
Гектометр Википедия говорит, что "very.unusual.@.unusual.com"@example.comэто действительный адрес электронной почты. /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test('"very.unusual.@.unusual.com"@example.com') // false, К сожалению.
биты
3
Разве это не позволяет @@@.@? : D
hfossli
764

Просто для полноты, здесь у вас есть еще одно регулярное выражение в соответствии с RFC 2822

Официальный стандарт известен как 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])+)\])

(...) Мы получим более практическую реализацию RFC 2822, если мы опустим синтаксис, используя двойные кавычки и квадратные скобки. Он по-прежнему будет соответствовать 99,99% всех адресов электронной почты, которые используются сегодня.

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

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

[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2}|com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum)\b

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

Акцент мой

вояджер
источник
84
NB: «На самом деле используется сегодня », возможно, был действительным, когда код был написан, еще в 200 раз. Код , вероятно, останется в использовании после этого конкретного года. (Если бы я ни копейки за каждый «Мех, никто никогда не будет использовать 4 + -Письмо TLD за исключением тех , специфические» Я должен был исправить, я мог бы угол в мире меди и никеля рынок;))
Piskvor покинул здание
7
Для практической реализации RFC 2822 окончание должно быть немного изменено, чтобы не допустить расширения одного домена символов. / [a-z0-9! # $% & '* + \ / =? ^ _ {|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_{|} ~ -] +) * @ (?: [a-z0-9] (?: [a-z0-9 -] * [a-z0-9])? \.) + [a-z0-9] [a-z0-9 -] * [a-z0-9] /
будет Фаррелл
5
Кроме того, первая часть должна быть (?: [Az с заглавной буквы A, чтобы избежать ложных негативов, когда пользователь вводит заглавные буквы в своем адресе электронной почты.
Дон Роллинг
9
@ DonRolling Не делай этого. Это не просто означает «от А до Я, от а до я», это также означает «[\] ^ _` », потому что они находятся между « Z »и« а ». Используйте \wили, что еще лучше, просто строчный адрес электронной почты, прежде чем что-либо делать с ним, потому что это соглашение в любом случае.
Кирб
5
«Вам нужно будет обновить его по мере добавления новых доменов верхнего уровня». Что ж, так много сейчас - существует более 1500 признанных доменов верхнего уровня.
Натан Осман
377

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

^\S+@\S+$

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

Jaymon
источник
70
+1, так как отправка электронной почты и просмотр того, что происходит, - это единственный реальный надежный способ подтвердить адрес электронной почты, нет необходимости делать больше, чем простое совпадение с регулярным выражением.
kommradHomer
20
Вы все еще можете сделать это простым, но сделайте немного больше, чтобы убедиться, что у него есть "." где-то после @, за которым следуют только цифры или цифры, поэтому такие вещи, как я @ здесь, я @ здесь @ и я @ herecom, недопустимы ... ^ \ S + @ \ S + [\.] [0-9a-z ] + $
Тим Франклин
14
Я думаю, что адреса электронной почты могут содержать пробелы. Это, вероятно, лучше использовать.+@.+
Сэм
11
/\S+@\S+/.test("áéíóúý@ÁÉÍÓÚÝð") true
Gtournie
111
@gtournie Никому нет дела. Никто не собирается вводить это в поле электронной почты случайно , и это все, что касается внешней проверки: для предотвращения случайного ввода неправильным битом информации, такой как их имя, в поле электронной почты.
Meagar
331

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

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

Паоло Бергантино
источник
112
-1 Зачем мне тратить время на проверку адреса электронной почты, который даже не проходит через регулярное выражение?
kommradHomer
63
@kommradHomer - неверный адрес регулярного выражения почти всегда действителен, потому что любое регулярное выражение, которое вы используете для проверки адреса электронной почты, почти наверняка неверно и исключит действительные адреса электронной почты. Адрес электронной почты name_part@domain_partи практически все, включая адрес @, действителен в name_part; Адрес foo@bar@machine.subdomain.example.museumявляется законным, хотя он должен быть экранирован как foo\@bar@machine..... Как только электронная почта достигает домена, например, «example.com», этот домен может направлять почту «локально», так что могут существовать «странные» имена пользователей и хостов.
Стивен П
6
Второе регулярное выражение в ответе voyager на stackoverflow.com/a/1373724/69697 является практичным для использования и не должно иметь почти никаких ложных отрицаний. Я согласен с @kommradHomer здесь - зачем отправлять электронную почту, если вам не нужно? Я могу понять рефлексивную неприязнь к непонятным регулярным выражениям и желание сохранить код простым, но это пара строк кода, которые могут избавить ваш сервер от многих проблем, немедленно отсеяв элементы, которые определенно недействительны. Регулярное выражение само по себе бесполезно, но служит хорошим дополнением к проверке на стороне сервера.
Бен Регенспан
6
@dmur Я признаю, что «почти всегда действительный», вероятно, преувеличивает его, но мои адреса электронной почты (совершенно действительные и рабочие) слишком часто отклоняются веб-сайтами, просто потому, что у меня есть .usдомен или потому, что я использовал +слева от во @многих местах исправлены эти вопиющие ошибки, но локальной частью (слева от @) может быть все, что хочет владелец домена. -> "foo@bar.com"@example.com <- это действующий адрес электронной почты.
Стивен П
8
@kommradHomer "Недопустимый адрес регулярного выражения -% 100 неверный адрес." Простите ... извините? Знаете ли вы, сколько раз мне говорили, что foo+bar@gmail.com НЕ является действительным электронным письмом, хотя на самом деле ЭТО СОВЕРШЕННО ДЕЙСТВИТЕЛЬНО ?! Ваша логика крайне ошибочна. Я отправил формы с электронными письмами как таковые: thisisafakeemailbutitwillpassyourstupidregexcheck@regexchecksareretarded.com И угадайте, что? Это проходит проверку REGEX ... но это НЕ действительный адрес электронной почты (хотя технически это ЕСТЬ, но я обещаю вам, что его не существует ... пока царапает его подбородок ). Как уже говорили многие, это
плохая
211

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

<form><input type="email" placeholder="me@example.com" required>
    <input type="submit">
</form>

jsFiddleссылка

Из спецификации HTML5 :

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

email   = 1*( atext / "." ) "@" label *( "." label )
label   = let-dig [ [ ldh-str ] let-dig ]  ; limited to a length of 63 characters by RFC 1034 section 3.5
atext   = < as defined in RFC 5322 section 3.2.3 >
let-dig = < as defined in RFC 1034 section 3.5 >
ldh-str = < as defined in RFC 1034 section 3.5 >

Это требование является преднамеренным нарушением 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])?)*$/
Anoop
источник
29
это хорошо, но проблема в том, что он должен быть внутри formтега и представлен submitвходом, что не каждый может себе позволить. Кроме того, вы не можете оформить сообщение об ошибке.
Джейсон
3
Я добавил ответ ниже, который освобождает вас от формы и отправки. Но да, браузеры обычно также применяют только некоторую проверку достоверности, а не полную проверку RFC 822.
Болдевин
8
@ br1: он недействителен только потому, что не существует домена верхнего уровня «а». почему ваша интрасеть имеет решимость на какой-то IP?
летающие овцы
7
Тип поля электронной почты Html5 принимает электронные письма, такие как user @ email
Puce
1
Примечание @ Комментарий Пуче: ввод электронной почты в HTML 5 допускается, user@emailтогда как, например, в PHP - filter_varнет. Это может вызвать проблемы.
texelate
136

Я считаю, что это лучшее решение:

/^[^\s@]+@[^\s@]+\.[^\s@]+$/

Это позволяет следующие форматы:

1. prettyandsimple@example.com
2. very.common@example.com
3. одноразовый. Style.email.with+symbol@example.com
4. other.email-with-dash@example.com
9. #!$%&'*+-/=?^_`abilities угадывающимся ~~@example.org
6. "() []:,; @ \\\"! # $% & '* + - / =? ^ _ `{} | ~ .A "@ example.org
7. "" @ example.org (пробел между кавычками)
8. üñîçøðé@example.com (символы Юникода в локальной части)
9. üñîçøðé@üñîçøðé.com (символы Юникода в доменной части)
10. Pelé@example.com (латиница)
11. δοκιμή@παράδειγμα.δοκιμή (греческий)
12. 買 買 @ 屋企. 香港 (китайский)
13. 斐 斐 @ 黒 川. 日本 (японский)
14. чебурашка@ящик-с-апельсинами.рф (кириллица)

Он, безусловно, универсален и допускает все важные международные символы, но при этом поддерживает базовый формат any@anything.anything. Это заблокирует пространства, которые технически разрешены RFC, но они настолько редки, что я с удовольствием это сделаю.

Эндрю
источник
9
Это именно то, что я делаю. Все эти «сложные» ответы порождают проблемы: они либо не допускают использование маленького кода IDN, либо используют фиксированный набор доменов верхнего уровня, либо излишне ограничивают пользователя, чтобы он не использовал символы, подобные [@ çµ.ö, в своем префиксе электронной почты (до @) или доменное имя. JavaScript во внешнем интерфейсе (не для внутреннего использования причины) недостаточно для проверки по соображениям безопасности. Так почему бы просто не помочь пользователю предотвратить основные опечатки. Основные опечатки: забудьте TLD или префикс пользователя (до @), часть домена или неправильный тип @как .(или наоборот). Конечно, мы должны быть более строгими на стороне сервера.
Hafenkranich
По некоторым странным причинам username@domain.comне работает с этим шаблоном
Эйнштейн
2
Согласно вашему регулярному выражению "_.............. kamal@gmail.com" является действительным, что не должно быть!
Камаль Наян
1
Вот заявленный RegEx с примерами, если вы хотите повозиться с этим решением: regex101.com/r/AzzGQU/2
ryanm
7
Это регулярное выражение верно. Если кто-то вводит свою электронную почту, как a@b@c@d.x.y.@.zтогда, может быть, они заслуживают плохого времени? : D
corysimmons
94

В современных браузерах вы можете опираться на ответ @ Sushil с помощью чистого JavaScript и DOM :

function validateEmail(value) {
  var input = document.createElement('input');

  input.type = 'email';
  input.required = true;
  input.value = value;

  return typeof input.checkValidity === 'function' ? input.checkValidity() : /\S+@\S+\.\S+/.test(value);
}

Я собрал пример в скрипке http://jsfiddle.net/boldewyn/2b6d5/ . В сочетании с обнаружением функций и простой проверкой Squirtle 's Answer он освобождает вас от расправы с регулярными выражениями и не работает в старых браузерах.

Boldewyn
источник
4
Это умная идея, чтобы разобраться с проблемой, но она не работает, потому что браузеры также имеют дрянную проверку. Например, .@aпроверяется как trueв текущих версиях Chrome, Firefox и Safari.
Хэнк,
13
@HenryJackson К сожалению, в этом случае да. Это потому, что в соответствии с RFC это действительный адрес электронной почты (например, интранет). Браузеры будут получать на гриле, если они проверяют слишком узко и выдают ложные негативы.
Болдевин
3
Обновлен, чтобы содержать функцию обнаружения и постепенное ухудшение качества, теперь он не ломается в новых браузерах, но использует любое регулярное выражение, которое вам нравится.
Ронни
Хорошее решение. К сожалению, это только для HTML5 +.
Эдвард Оламисан
3
Это, безусловно, лучшее решение исходного вопроса. Да, он использует HTML5, но большинство приложений, которым требуется такой уровень точности, наверняка уже будет в любом случае полагаться на HTML5, так что спорный вопрос. Мы никогда не сможем определить, является ли чья-то электронная почта действительной, не заставляя их проверять ее, так или иначе, поэтому нам не следует тратить столько времени или усилий на ее проверку. Быстрая проверка на любой очевидный синтаксис или попытку наглости - все усилия, которые мы должны приложить.
Вуди Пэйн
69

Это правильная версия RFC822.

function checkEmail(emailAddress) {
  var sQtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]';
  var sDtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]';
  var sAtom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+';
  var sQuotedPair = '\\x5c[\\x00-\\x7f]';
  var sDomainLiteral = '\\x5b(' + sDtext + '|' + sQuotedPair + ')*\\x5d';
  var sQuotedString = '\\x22(' + sQtext + '|' + sQuotedPair + ')*\\x22';
  var sDomain_ref = sAtom;
  var sSubDomain = '(' + sDomain_ref + '|' + sDomainLiteral + ')';
  var sWord = '(' + sAtom + '|' + sQuotedString + ')';
  var sDomain = sSubDomain + '(\\x2e' + sSubDomain + ')*';
  var sLocalPart = sWord + '(\\x2e' + sWord + ')*';
  var sAddrSpec = sLocalPart + '\\x40' + sDomain; // complete RFC822 email address spec
  var sValidEmail = '^' + sAddrSpec + '$'; // as whole string

  var reValidEmail = new RegExp(sValidEmail);

  return reValidEmail.test(emailAddress);
}
бвл
источник
Адреса IDN не подтверждены (info@üpöü.com)
DAH
66

JavaScript может соответствовать регулярному выражению:

emailAddress.match( / some_regex /);

Вот регулярное выражение RFC22 для электронных писем:

^((?>[a-zA-Z\d!#$%&'*+\-/=?^_`{|}~]+\x20*|"((?=[\x01-\x7f])[^"\\]|\\[\x01-\x7f])*
"\x20*)*(?<angle><))?((?!\.)(?>\.?[a-zA-Z\d!#$%&'*+\-/=?^_`{|}~]+)+|"((?=[\x01-\x
7f])[^"\\]|\\[\x01-\x7f])*")@(((?!-)[a-zA-Z\d\-]+(?<!-)\.)+[a-zA-Z]{2,}|\[(((?(?<
!\[)\.)(25[0-5]|2[0-4]\d|[01]?\d?\d)){4}|[a-zA-Z\d\-]*[a-zA-Z\d]:((?=[\x01-\x7f])
[^\\\[\]]|\\[\x01-\x7f])+)\])(?(angle)>)$
Бен Шейрман
источник
1
@Kato: он использует некоторые несовместимые расширения, в том числе, (?>чтобы прекратить возвращаться назад и (?<angle><)…(?(angle)>)избегать длинных |.
Ry-
60

Все адреса электронной почты содержат символ «at» (то есть @). Проверьте это необходимое условие:

email.indexOf("@") > 0

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

Чтобы проверить это, отправьте сообщение проверки.

полковник Panic
источник
3
что если будет более одного символа '@'? другие запрещенные символы? Этой проверке нельзя доверять ...
eatmypants
56

Корректная проверка адреса электронной почты в соответствии с RFC не может быть достигнута с помощью регулярного выражения, состоящего из одной строки. Статья с лучшим решением, которое я нашел в PHP: « Что такое действительный адрес электронной почты? , Очевидно, он был портирован на Java. Я думаю, что функция слишком сложна для переноса и использования в JavaScript. Порт JavaScript / node.js: https://www.npmjs.com/package/email-addresses .

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

Вот функция JavaScript, которую я использую, чтобы проверить, похожа ли строка на действительный почтовый адрес:

function looksLikeMail(str) {
    var lastAtPos = str.lastIndexOf('@');
    var lastDotPos = str.lastIndexOf('.');
    return (lastAtPos < lastDotPos && lastAtPos > 0 && str.indexOf('@@') == -1 && lastDotPos > 2 && (str.length - lastDotPos) > 2);
}

Объяснение:

  • lastAtPos < lastDotPos: Last @должен быть перед последним, .поскольку @не может быть частью имени сервера (насколько я знаю).

  • lastAtPos > 0: Должно быть что-то (имя пользователя электронной почты) перед последним @.

  • str.indexOf('@@') == -1: Не должно быть @@в адресе. Даже если @в имени пользователя электронной почты он указан как последний символ, он должен быть заключен в кавычки, поэтому он "должен находиться между @последним и последним @в адресе.

  • lastDotPos > 2Например, перед последней точкой должно быть не менее трех символов a@b.com.

  • (str.length - lastDotPos) > 2: После последней точки должно быть достаточно символов для формирования двухсимвольного домена. Я не уверен, что скобки необходимы.

Милош Рашич
источник
Этот fn выглядит хорошо, но лучше ли это, чем регулярное выражение, написанное в верхнем ответе?
Атул Гоял
4
Я сомневаюсь в этом. Я использую его только для проверки того, выглядит ли строка как электронное письмо, и оставляю детали для кода на стороне сервера.
Милош Рашич
Он проверяет правильность любой строки, например, «aaaa», то есть без «@» и «.»
Геннадий Шумахер
1
Это не должно lastIndexOf () должен вернуть -1, если не находит стрелку.
Милош Рашич
«Даже если @в имени пользователя электронной почты он указан как последний символ, он должен быть заключен в кавычки, поэтому он "должен быть между этим @и последним @в адресе». Как насчет "@@"@example.com?
Ry-
47

Это было украдено с http://codesnippets.joyent.com/posts/show/1917

email = $('email');
filter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
if (filter.test(email.value)) {
  // Yay! valid
  return true;
}
else
  {return false;}
Адам Макки
источник
7
Это отфильтровывает все популярные .museumи .travelдомены (из-за лимита в 4 символа после .)
bobobobo
4
Изменение {2,4} на {2,6} не будет проблемой
Антон Н
11
@Anton N: у него также есть около миллиарда других проблем; последний {2,4}- просто полезный индикатор этого (например, «когда вы видите эту ошибку, другие, вероятно, будут рядом»). Самые основные из них является отсутствие +в локальной части; это поле для комментариев слишком мало, чтобы указывать на все ошибки, допущенные выше.
Писквор покинул здание
37
Почему ты не можешь просто сделать return filter.test(email.value);?
MT.
3
@AntonN: теперь у нас есть 10+ TLD ( xn--clchc0ea0b2g2a9gcd). Все еще не проблема?
Писквор покинул здание
42

Сделай это:

[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])?

Почему? Он основан на RFC 2822 , который является стандартным ВСЕМ адресам электронной почты, которые ДОЛЖНЫ придерживаться. И я не уверен, почему вы возитесь с чем-то «более простым» ... вы все равно скопируете и вставите его;)

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

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

Вот пример его использования в JavaScript (с нечувствительным к регистру флагом iв конце).

var emailCheck=/^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i;
console.log( emailCheck.test('some.body@domain.co.uk') );

Примечание .
Технически некоторые электронные письма могут содержать кавычки в разделе перед @символом с escape-символами внутри кавычек (поэтому ваш почтовый пользователь может быть неприятным и содержать такие вещи, как @и "..."до тех пор, пока он написан в кавычках). ЭТО НИКОГДА НЕ ДЕЛАЕТ! Это устарело. Но он включен в настоящий стандарт RFC 2822 и здесь опущен.

Дополнительная информация: http://www.regular-expressions.info/email.html

Райан Тейлор
источник
@Kondal код javascript не чувствителен к регистру из-за /iфлага в конце регулярного выражения. Я упоминаю тот факт, что это должно быть сравнение без учета регистра, но я сделаю это более ясным.
Райан Тейлор
Работал для меня как шарм
Алекс
40

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

  • оригинал
    /^(([^<>()\[\]\\.,;:\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,}))$/

  • модифицированный
    /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()\.,;\s@\"]+\.{0,1})+[^<>()\.,;:\s@\"]{2,})$/

передать примеры в адрес электронной почты Википедии .

И вы можете увидеть результат здесь .

введите описание изображения здесь

Кейт Ли
источник
Это кажется хорошим решением, оно работает и с новыми TLD, и с 1-м письмом
Марк Хьюз
Почему john..doe@example.comдолжно быть не правильно? Это действительный угловой случай.
Валерио Бозз
24

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

Теперь, поскольку вы можете охватить только 90% случаев, напишите что-то вроде:

function isPossiblyValidEmail(txt) {
   return txt.length > 5 && txt.indexOf('@')>0;
}

Вы можете уточнить это. Например, 'aaa @' допустимо. Но в целом вы понимаете суть. И не увлекайтесь ... Простое решение на 90% лучше, чем решение на 100%, которое не работает.

Мир нуждается в более простом коде ...

Zo72
источник
15
Это позволяет вводить столько недействительных адресов электронной почты, что это бесполезный совет.
cazlab
3
Это не должно быть невозможно отладить вообще. В этой теме есть много прекрасных примеров, которые проверяют дальше, чем «содержит ли он @». Ваш пример позволяет считать «u @» действительным адресом электронной почты. По крайней мере, оцените, есть ли домен или что-то, что может быть доменом. Ваш пример того, что я бы назвал «агрессивно-ленивым кодированием». Я не уверен, почему вы защищаете его, так как это безусловно самый низкий рейтинг в ветке.
cazlab
3
@cazlab возможно ты прав. В конце концов я был отклонен. В отличие от вас, я не думаю, что любой из приведенного выше кода показывает легко отлаживать фрагменты. Мой «агрессивно ленивый» подход, по крайней мере, может быть улучшен при необходимости.
Zo72
3
Чем это отличается от использования регулярных выражений? (.+)@(.*)делает то же самое и короче.
snostorm
4
+1 - если цель состоит в том, чтобы убедиться, что пользователь хотя бы попытался ввести адрес электронной почты, то проверьте, можно ли определить, что адрес электронной почты определенно НЕ является адресом электронной почты. отличное решение. Хорошим примером будет, если вы хотите, чтобы имя пользователя было адресом электронной почты. Если пользователь вводит «sexy_chick_23», то это регулярное выражение можно использовать, чтобы предупредить его, что ожидается электронное письмо. Если набрано что-то похожее на электронное письмо, но это не так, то пользователь никогда не получит электронное письмо с подтверждением и процесс регистрации никогда не будет подтвержден.
Крис Датроу
23

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

<input type="email"/>

Нет необходимости писать функцию для проверки.

учащихся
источник
4
IE <10 не поддерживает это, как и собственный браузер Android.
Фрэнк Конейн,
7
Upvoting. IE <10 мертв.
Майкл Шепер
19

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

Некоторые вещи для улучшения:

Вместо нового RegExpпросто попробуйте написать regexpтак:

if (reg.test(/@/))

Во-вторых, убедитесь, что точка стоит после @знака, и убедитесь, что между символами @s и точками есть символы .

jacobangel
источник
19

Вот как это делает узел-валидатор :

/^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[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]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/
pera
источник
14

Используйте этот код внутри вашей функции валидатора:

var emailID = document.forms["formName"]["form element id"].value;
atpos = emailID.indexOf("@");
dotpos = emailID.lastIndexOf(".");
if (atpos < 1 || ( dotpos - atpos < 2 ))
{
    alert("Please enter correct email ID")
    return false;
}

Еще вы можете использовать jQuery . Внутренние правила определяют:

eMailId: {
    required: true,
    email: true
}
орхидея
источник
1
abc@xyzявляется совершенно действительным адресом электронной почты, который не распознается вашим регулярным выражением.
Тото
3
Нет, это не так. Правильный шаблон электронной почты - что-то@something.something, abc @ xyz не соответствует этому шаблону. Так что это не правильный адрес.
Орхидея
Посмотрите здесь: en.wikipedia.org/wiki/Email_address#Valid_email_addresses
Toto
5
У вас была страница в Википедии? ДВУ - это действительное имя хоста. Так abc@tldже действительный адрес электронной почты.
Тото
2
Единственный способ подтвердить адрес электронной почты - это отправить письмо и дождаться ответа. Кроме того, вот URL, где вы можете проверить, соответствует ли ваш адрес RFC822: mythic-beasts.com/~pdw/cgi-bin/emailvalidate . Вы можете видеть, что abc @ xyz является действительным адресом для RFC822.
Тото
14

Regex обновление 2018 года! попробуй это

let val = 'email@domain.com';
if(/^[a-z0-9][a-z0-9-_\.]+@([a-z]|[a-z0-9]?[a-z0-9-]+[a-z0-9])\.[a-z0-9]{2,10}(?:\.[a-z]{2,10})?$/.test(val)) {
   console.log('passed');
}

полная версия

//
export const emailValid = (val:string):boolean => /^[a-z0-9][a-z0-9-_\.]+@([a-z]|[a-z0-9]?[a-z0-9-]+[a-z0-9])\.[a-z0-9]{2,10}(?:\.[a-z]{2,10})?$/.test(val);

больше информации https://git.io/vhEfc

Хуан Пабло
источник
Это не удалось , для стандартного email@domain.com
Рикс
1
@RickS это просто не правда. Пожалуйста, проверьте еще раз
Малимо
13

Решение, которое не проверяет существование TLD, является неполным.

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

1- Проверка формата электронной почты. Убедитесь, что электронная почта соответствует формату и шаблону электронных писем в RFC 5322 и действительно ли существует TLD. Список всех действительных TLD можно найти здесь .

Например, хотя адрес example@example.cccбудет проходить регулярное выражение, он не является действительным электронным письмом, поскольку cccIANA не является доменом верхнего уровня.

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

оборота бман
источник
13

Regex для проверки адреса электронной почты

[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])+
Prabhat Kasera
источник
Я не вижу вашего регулярного выражения в RFC5322: tools.ietf.org/html/rfc5322 - есть какая-то ошибка?
Камиль Келчевски
"Лучшее регулярное выражение когда-либо"? Возможно, какое-то объяснение здесь?
connectyourcharger
Почему вы сказали, что это лучшее решение из всех, можете ли вы объяснить немного больше, пожалуйста?
Нанкодер
Я не могу вспомнить, почему я написал «лучшее когда-либо регулярное выражение». Извините, ребята, если это вас беспокоит.
Прабхат Касера
12

Вот очень хорошая дискуссия об использовании регулярных выражений для проверки адресов электронной почты; " Сравнение адреса электронной почты, проверяющего регулярные выражения »

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

/^[-a-z0-9~!$%^&*_=+}{\'?]+(\.[-a-z0-9~!$%^&*_=+}{\'?]+)*@([a-z0-9_][-a-z0-9_]*(\.[-a-z0-9_]+)*\.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|mobi|[a-z][a-z])|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,5})?$/i
Эрик Шуновер
источник
9
-1 Белый список оставляет желать лучшего - в частности, вы пропустили .jobs. Кроме того, существуют живые ИДИ (большинство из которых, я признаю, были официально одобрены только после вашего поста - например, .中國в июне 2010 года; но большинство работали годами).
Писквор покинул здание
2
-1 не используйте постоянные домены верхнего уровня. Там всегда (и будет, например, 2013) могут быть добавлены новые TLD.
Михо
Подтверждено 100 новых TLD. Этот ответ недействителен и никогда не должен использоваться.
Дин Михан
Ага. Я сказал это в 2011 году, и еще раз скажу: белый список «специальных» доменов со временем будет только ухудшаться, так как будет утверждено больше ДВУ. Существует более 100 полностью действительных
доменов верхнего уровня,
Это 2015 год. Ваше выражение не практично. Вы должны записать этот ответ, но вы, вероятно, слишком заняты исправлением всех страниц, на которых написано это выражение. Правильно?
Эрик Леруа,
12

Видимо, вот и все:

/^([\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

Взято с http://fightingforalostcause.net/misc/2006/compare-email-regex.php 1 октября 2010 года.

Но, конечно, это игнорирование интернационализации.

Феликс Сапарелли
источник
12

В отличие от Squirtle , здесь есть сложное решение, но оно отлично справляется с проверкой электронной почты:

function isEmail(email) { 
    return /^((([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.test(email);
} 

Используйте так:

if (isEmail('youremail@yourdomain.com')){ console.log('This is email is valid'); }
Стив
источник
10
Вам не нужно == trueна вашем примере.
Люк Олдертон
11

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

Наиболее распространенные ошибки, с которыми я сталкиваюсь, - это пробелы (особенно в начале и в конце) и иногда двойная точка.

function check_email(val){
    if(!val.match(/\S+@\S+\.\S+/)){ // Jaymon's / Squirtle's solution
        // Do something
        return false;
    }
    if( val.indexOf(' ')!=-1 || val.indexOf('..')!=-1){
        // Do something
        return false;
    }
    return true;
}

check_email('check@thiscom'); // Returns false
check_email('check@this..com'); // Returns false
check_email(' check@this.com'); // Returns false
check_email('check@this.com'); // Returns true
Linkmichiel
источник
10
<form name="validation" onSubmit="return checkbae()">
    Please input a valid email address:<br />

    <input type="text" size=18 name="emailcheck">
    <input type="submit" value="Submit">
</form>

<script language="JavaScript1.2">
    var testresults
    function checkemail(){
        var str = document.validation.emailcheck.value
        var filter = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i
        if (filter.test(str))
            testresults = true
        else {
            alert("Please input a valid email address!")
            testresults = false
        }
        return (testresults)
    }
</script>

<script>
    function checkbae(){
        if (document.layers || document.getElementById || document.all)
            return checkemail()
        else
            return true
    }
</script>
Tugrul Asik
источник
Может быть, если вы добавили объяснение или описание, чтобы пойти с ним? Я не думаю, что вам действительно нужно показывать какие-либо HTML; все люди обеспокоены, это Javascript и регулярное выражение. Если вы сведете свой ответ только к jacascript и добавите небольшую рекламу, я дам вам голос.
bgmCoder
9

Я искал Regex в JS, который проходит все тестовые случаи адреса электронной почты:

  • email@example.com Действительный адрес электронной почты

  • firstname.lastname@example.com Письмо содержит точку в поле адреса

  • email@subdomain.example.com Письмо содержит точку с поддоменом

  • firstname+lastname@example.com Знак плюс считается действительным символом

  • email@192.0.2.123 Домен является действительным IP-адресом

  • email@[192.0.2.123] Квадратная скобка вокруг IP-адреса считается действительной

  • “email”@example.com Цитаты по электронной почте считаются действительными

  • 1234567890@example.com Цифры в адресе действительны

  • email@domain-one.example Тире в доменном имени действительна

  • _______@example.com Подчеркивание в поле адреса является действительным

  • email@example.name .name действительное имя домена верхнего уровня

  • email@example.co.jpТочка в доменном имени верхнего уровня также считается действительной (в co.jpкачестве примера здесь)

  • firstname-lastname@example.com Тире в поле адреса действительна

Вот так :

http://regexr.com/3f07j

ИЛИ регулярное выражение:

Regex = /(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@[*[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+]*/
Negin
источник
8

Регулярное выражение, предоставляемое Microsoft в ASP.NET MVC :

/^[\w-]+(\.[\w-]+)*@([a-z0-9-]+(\.[a-z0-9-]+)*?\.[a-z]{2,6}|(\d{1,3}\.){3}\d{1,3})(:\d{4})?$/

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

Нил Томпсон
источник
1
Не позволяет + в части имени электронной почты.
Пол Го