Как стать автором
Обновить

Комментарии 122

а если завтра введут новый домен, переделывать все рэги?)
и в чем я не прав?
а если завтра ввдеуть новый язык разметки, переделывать все сайты?
в данном случае надо всего лишь универсальное крепление для колеса добавить, а не переделывать машину заново.
НЛО прилетело и опубликовало эту надпись здесь
Сагалаев на этот счёт писал, что и от правильной RFC-шной валидации толку немного. Во-первых, потому что не все почтовые серверы так требовательны, и существуют емэйлы, не соответствующие RFC, и вполне валидные. Во-вторых, обратное: не все RFC-валидные емэйлы существуют на самом деле. В-третьих, если они существуют, не факт, что их кто-то читает. И если читает, то не факт, что понимает :)

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

(пользуясь случаем, посылаю еще один луч ненависти тем, кто «+» в username не разрешает)
Луч ваш поймал, спасибо. Плюс разрешать всё равно не буду :-)
Чёрт, проверил только что — а ведь плюсик-то разрешён :-) Я и забыл — давно дело было. Луч возвращаю.
а вот из Django: code.djangoproject.com/browser/django/trunk/django/forms/fields.py#L422

email_re = re.compile(
    r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*"  # dot-atom
    r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string
    r')@(?:[A-Z0-9-]+\.)+[A-Z]{2,6}$', re.IGNORECASE)  # domain
во второй строчке на меня подозрительно хмурятся два смайлика…
^_`
Валиден ли следующий email (не по RFC, а в реальности): ----@----.----
В домене нельзя больше 2 "-" подряд.
Вот вот, а «самый надежный» регэксп, написаный по RFC, это допускает.
Гм, не знал.
Сорри за общественную дезинформацию.
а теперь все правильно — хром блокирует с ошибкой DNS_PROBE_FINISHED_NXDOMAIN.
а как же punnycode, например xn--suz.net?
Поэтому я и сказал — больше 2.
В punycode — ровно два.
не, это можно, но нельзя начинать имя с минуса
Это уже не регэксп, а матрица какая-то о__О
О, спасибо за filter_var()!
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Вы считали не правильно. 63 — длинна одного «куска» домена от точки до точки, весь домен может быть длинной 255 символов (с точками, iirc).
НЛО прилетело и опубликовало эту надпись здесь
Я делаю проверку вне регэкспа.
А где проверка существования домена второго и последующих уровней? А иначе какой смысл проверять домены первого уровня?
Хм. Это проверятся контрольным email'ом по адресу.
в копилку вариантов:
/\\A(?:^([a-z0-9][a-z0-9_\\-\\.\\+]*)@([a-z0-9][a-z0-9\\.\\-]{0,63}\\.([a-z]{2,4}))$)\\z/i
Я понял что нельзя затрагивать столь спорную тему. Даже для попытки обучения. :)

В следующий раз возьмем тему нейтральнее.
НЛО прилетело и опубликовало эту надпись здесь
Почему же сразу бессмысленна? Обычный хороший тон — проверка пользовательских данных. Плюс именно так работает двухшаговая схема регистрации: сначала пользователь регистрируется, а потом подтверждает регистрацию по электронной почте.
НЛО прилетело и опубликовало эту надпись здесь
А если сервер временно недоступен? А если там стоит проверка на спам? Забыл как называется, ныне очень популярный метод у админов — не отвечать на первую попытку положить письмо, нормальный SMPT повторит попытку минут через 15 — но это значит, что для проверки пользователю придётся ждать 15 минут.

Ну и «проверка должна быть качественной» — расплывчатый тезис. Это как с любыми другими полями ввода — достаточно ли убедиться что почтовый индекс состоит из 6 цифр, или надо держать у себя базу корректных почтовых индексов?

С базой всё хорошо, только как поддерживать актуальность информации? Если поддерживать, то сразу задача становится непростой и организационной. Потому, на мой взгляд, достаточно убедиться, что в индексе 6 цифр. И убедиться, что электронный адрес похож на настоящий.
НЛО прилетело и опубликовало эту надпись здесь
Проблема в том, что свой почтовый сервер отправляет письмо чужому почтовому серверу. Который может дать отлуп на совершенно корректный адрес.

> Проверка индекса на 6 цифр — это, кстати, отличный пример некачественной проверки
> (если не оговорить ещё несколько условий).

Например, каких? Почтовые индексы можно проверить только базой, там нет избыточности, как в номерах банковских счетов. Вопрос — где вы будете брать актуальную базу и сколько это будет стоить? Окупается ли это, т. н. качество?
Поискал по интернету, нашёл эталонный справочник почтовых индексов вот здесь: info.russianpost.ru/database/ops.html#newdbdata

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

1. Проверяем, обновился ли файл info.russianpost.ru/database/PIndx.zip с момента последнего скачивания (надеюсь, If-Modified-Since они поддерживают, иначе совсем грустно).

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

3. Распаковываем архив, получаем DBF.

4. Из DBF перегоняем данные в нашу собственную базу.

5. В случае необходимости проверяем индекс по базе.

Реально? Реально. Нужно? На мой взгляд, спорно. Если есть свободное время, почему бы и нет. Но это отнюдь не первоочередная задача.
НЛО прилетело и опубликовало эту надпись здесь
Ну а какая альтернатива то? Либо «на шесть цифр», либо вот так.

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

Или комическую ситуацию, которая довольно часто встречается: «я случайно положил деньги на ваш телефон, положите столько на телефон хххххххх». :)
НЛО прилетело и опубликовало эту надпись здесь
> Доставка по постсоветскому пространству от индекса не зависит. Дойдет
> и без него. Дойдет и с ошибочным. Проверено.

В данном конкретном случае согласен. Но это никак не отменяет необходимости проверки пользовательского ввода в целом.

В частности, электронную почту всё-таки проверяют регекспом, это разумно.
НЛО прилетело и опубликовало эту надпись здесь
Если мне не изменяет память, этот регексп учитывает и такие адреса, как [«Вася Пупкин» vasya2003@pupmail.net] — почтовый адрес в квадратных скобках. Мне лично кажется, что это излишество.
НЛО прилетело и опубликовало эту надпись здесь
> Проблема в том, что фразой «если мне не изменяет память»
> не отделаешься, это непрофессионально.

Вообще то нет. Можно один раз разобраться, потом забыть подробности.

> Нужно знать точно, какие проверки сделать. Чтобы знать
> точно, нужно вначале изучить RFC, а потом на его основе
> кодировать. Я считаю это напрасной тратой времени и при
> любой возможности перекладываю такой контроль на
> сторонние средства, где это уже реализовано. А трата
> времени на недорешения с псевдоконтролем чревата
> последующими эксплуатационными проблемами.

Любой подход чреват эксплуатационными проблемами. Тем более подход «перекладывания на сторонние средства». Их ведь надо протестировать на соответствие RFC, а это тоже трата времени. Если не тестируете, рискуете получить проблемы там, где их не ожидали.
НЛО прилетело и опубликовало эту надпись здесь
Согласен.

В принципе, я тоже сторонник готовых решений. Но, скажем так, в общеобразовательных целях люблю решать задачи, в том числе и такие, не имеющие даже практической ценности.
ну и еще вариант: /^[0-9a-z]([\.-]?\w+)*@[0-9a-z]([\.-]?[0-9a-z])*(\.[0-9a-z]{2,4})+$/
Пример не рабочий в валидации hostname у вас…
Пожалуйста, объясните.
Нажмите на ссылку «Пример» и сами все уведите ;)
Странно все это. В firefox меня редиректит на ai.com, а ie не открывает вообще.
Вообщем об этом я узнал в книге, посмотрел в firefox и подумал что так должно быть.
Чтобы зайти, надо писать «ai.»
Запись у корневого домена действительно есть:
[borisko@vaiofw ~]$ whois -h whois.iana.org ai
[Querying whois.iana.org]
[whois.iana.org]

IANA Whois Service
Domain: ai
ID: ai
[skip]
Nameserver Information:
Nameserver: ns1.pair.com.
IP Address: 209.68.1.11
Nameserver: ns2.offshore.ai.
IP Address: 208.75.85.241
Nameserver: whois.ai.
IP Address: 209.59.119.1

Registration Date: 16-February-1995
Last Updated Date: 21-November-2007
[borisko@vaiofw ~]$ dig @209.68.1.11 ai A
[skip]
;; ANSWER SECTION:
ai. 14400 IN A 209.59.119.34
[skip]
[borisko@vaiofw ~]$
Спасибо, исправил. А если на этом домене есть мыло, отправляться должно тоже с точкой?
Мыло на нем тоже есть %)
[borisko@vaiofw ~]$ dig @209.68.1.11 ai MX
[skip]
;; QUESTION SECTION:
;ai.                            IN      MX

;; ANSWER SECTION:
ai.                     14400   IN      MX      10 mail.offshore.ai.
[skip]
[borisko@vaiofw ~]$ 

Думаю, да.
Хотя exim у меня не отправил ни с точкой, ни без.
ну в принципе уже обсуждаемое:
"/^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,4}|[0-9]{1,4})(\]?)$/"
Вариант валидации email из CakePHP:
"/^[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[a-z]{2,4}|museum|travel)$/i"
интересно, а если админ сайта захочет найти частичным совпадением в базе мыло, которое содержит %? =)
Я бы не советовал с фанатизмом подходить к вопросу проверки email'ов. Когда я ее использую, то ставлю цель формально проверить, что пользователь не ввел чепухи, а так же, чтобы он сам не ошибился, забыв собаку или точку. Если так хочется убедиться, что адрес существующий, лучше ввести подтверждение по почте, чем городить трехэтажные конструкции из регулярных выражений.
Я такого-же мнения, но все же проверяю email регэкпами.
думал зачем поднимается подобная тема, в гугле можно найти десяток вариаций на эту тему.
но даже такого ужоса не ожидал.
вот какой смысл проверять домены первого уровня более двух символов, если при этом условие для двухбуквенных позволит ввести некоректную страну?
ну и очень актуальная проблема, что для внутрикорпоративного использования не подходит: manager1@callcenter.server
Вот-вот. Это не говоря про адреса вроде username@localhost или username@192.168.1.2 — такие вообще почти никогда не валидируются.
Спустя три года всё же уточню, на случай, если кому-то интересно. Для того, чтобы указать, что письмо надо отправить на сервер по IP-адресу (а не по hostname), IP-адрес необходимо поместить в квадратные скобки, то есть:

username@[192.168.1.2]

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

Кстати, в Википедии можно найти ещё много интересных вариантов необычных (но корректных) email-адресов. Бо́льшая часть регулярных выражений, кстати, не принимает многие из них за корректные. И наоборот — ниже приводятся некорректные адреса, и, опять же, многие из них обычно проходят валидацию.
НЛО прилетело и опубликовало эту надпись здесь
Не раз обсуждалось.
НЛО прилетело и опубликовало эту надпись здесь
Вот regexp из довольно старой, но хорошей книги «Профессиональное PHP программирование»:
^[_\-\.0-9a-z]+"([0-9a-z][_0-9a-z\.]+)\.([a-z]{2,4}$)
Суть такова:
Имя ящика начинается с одного или нескольких буквенно-цифровых символов, за которыми следует @. Допустимы также точка, подчеркивание и дефис.
Имя хоста содержит одну или более точек и оканчивается строкой длины от 2 до 4 символов.

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

Я, впрочем, просто хотел немного разжевать.
а как же .museum и .travel?
Мне кажется, проверка tld все равно нужна жесткая. Не так часто они и добавляются.
Ну, есть понятие ошибок первого и второго рода.
В данном случае, случайно не пропустить куда болезненнее, чем случайно пропустить неправильное. Поэтому жесткая проверка tld таит в себе немало проблем.
Домен первого уровня может состоять из любых 4 латинских букв, например .habr

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

Как сказали выше, глупо перечислять все доменные зоны из более чем трех символов. Достаточно [a-z]{2,6}. А учитывая регистрацию доменов первого уровня, ваши регекспы можно просто выкинуть.

Ну и наконец, информации об этом настолько много, что ваши «статьи» — надоедливое переливание из пустого в порожнее.
Абсолютно согласен. Я изредка вспоминаю про свой блог и знаю, что писать про то, что уже написано, нельзя. Взяли давно изжеваную тему. Не ново, совсем не ново…
Имя пользователя может в себе содержать:

* латиницу
* цифры
* знаки! # $ % & ' * + — / =? ^ _ ` { | } ~

что курит афтар, вставляя всё это (и кавычки!!!) в имена юзеров?
«Ваш мозг сделан по стандарту» (с)
очень интересно посмотреть на то, как вы в базе будете хранить юзернейм с кавычкой и к какой магии прибегните, чтобы юзер мог нормально функционировать ;)
Какие, если не секрет, проблемы в том, чтобы хранить кавычки в базе?
Вы что! Это же страшная тайна профессиональных php-программистов! :)
Ах да, little Bobby Tables. Мы помним.
а ещё если вы внимательно посмотрите свою ссылку, то увидите:

RFC invalid e-mail addresses

* Abc.example.com (character @ is missing)
* Abc.@example.com (character dot(.) is last in local part)
* Abc..123@example.com (character dot(.) is double)
* A@b@c@example.com (only one @ is allowed outside quotations marks)
* ()[]\;:,@example.com (none of the characters before the @ in this example, are allowed outside quotation marks)

вообще создается впечатление, что вы никогда систем регистрации не делали =)))
а ну да. подходит, сорри =)

но все равно "!#$%&'*+/=?^_`{|}~" и прочий бред в мыле не должен быть, просто следуя здравому смыслу.
Тут все противоречиво. Одни говорят RFC и все дела, другие твердаят про здравый смысл.
Господа, а как же IDN?

Я бы понимал \w, но уж никак не [a-z].
Вообще-то, local part может даже символ 0 (\0) содержать, а доменная часть — -путевой адрес через восклицательные знаки… Учим мат-часть (RFC).
Вот и баг. Хабр ссылки не корректно определяет, разработчики не учили мат часть.
Мне этот регэксп будет сниться.
У меня как-то юзер на сайте зарегистрировался с таким адресом (имя я изменил):
www.vasya@meil.ru

Вообще, несколько раз ввв приделывали в начале.
А что, такие e-mail вполне могут быть валидны.
Могут быть, да. Но не валидны :-)

А потом такие юзеры жалуются, что им не приходит письмо с ключом авторизации.
У меня был юзер с mail.ru и с www. вначале. Без ошибки.

Однако да, обычно что только народ не пытается в поле адреса писать…
оу меня тоже пачка таких, причем все с www именно на mail.ru лол
Ха! У меня отдельные личности не различают пароль на VKontakte и на корпоративный прокси-сервер. Тут уж только лоботомия, боюсь, поможет, regexp'ы бессильны.
бредово как-то проверять имейлы именно...\
лучше ипишники откуда коннектятся, имо.\
я делаю так, и результаты более чем
Я туплю, или в списке доменов нет «ru»?
[a-z][a-z]
> точку, за исключением первого и последнего знака, которая не может повторятся
эээээттооо еще как — не может повторяться?
you.will.be@satisfied.org.ua — две точки.

upd. или вы имеете в виду отсутствие двух точек подряд?..
test@mail.com проходит всегда :)
fuck@the.usa обычно тоже :)

И таких е-мейлов масса.
Слышал существует возможность проверки имейла на сучествование на сервере.

Кто ни будь сталкивался?
Я сталкивался и даже делал. Есть одна, а точнее 3 больших проблемы:

1) SMTP Delay;
2) Greylisting;
3) Корпоративные релеи, которые едят всю почту на любой логин;

В общем, кровь портит борьба со спамом.

Поэтому у себя ограничился проверкой наличия mx-записи у введеного домена. При отсутствии, соответственно отлуп. Это кстати, тоже противоречит RFC ибо при отсутствии mx по RFC почта должна уходить куда-то на A-запись.
Благадарю примим к сведению.
НЛО прилетело и опубликовало эту надпись здесь
По поводу доменов первого уровня. Если хотите проверять универсально, держите у себя копию файла data.iana.org/TLD/tlds-alpha-by-domain.txt и обновляйте регулярно. Там перечислены все актуальные домены верхнего уровня.
search.cpan.org/~pdwarren/Mail-RFC822-Address-0.3/Address.pm

Mail::RFC822::Address: regexp-based address validation

This regular expression will only validate addresses that have had any comments stripped and replaced with whitespace (this is done by the module).

(?:(?:\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*)


плак :)
Адд!
Мои скромные 5 копеек — список расширений доменов неплохо бы проверять точнее.
В Вашем варианте мейл cool_hacker_will@fool.yo будет валидным.
А список доменов буде выглядеть так:
aero|biz|com|coop|edu|eu|gov|info|int|mil|museum|name|net|org|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw
Я убедился, что достаточно проверить на @ и точку.
не заметил в этом списке домена рф
НЛО прилетело и опубликовало эту надпись здесь
Суффикс предлагаю записать так: [a-zа-я]{2,}
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории