Website development
IT Standards
Comments 99
-23
Согласен, соблюдать стандарты — пустая трата времени.

Вообще всегда были подозрительны люди в яшиками не в формате imyafamiliya334356@mail.ru
+8
Вообще всегда были подозрительны люди в яшиками не в формате imyafamiliya334356@mail.ru

У людей просто нет фантазии, а все нормальные ники заняты )
+7
Люди такие, и фантазии нет, и без таблички «сарказм» к ним лучше не ходить…
0
Подробно не сумею, но вот кратко — посмотрите в мой профиль и сравните со своим. На абсолютные значения кармы можно даже внимания не обращать, тут важно сколько людей там отметилось вообще. Итого можно сделать вывод — около 50% людей не любят сарказм при любом раскладе.
0
Великий Гуро! Простите много мнящего о себе новичка! Я не вдохнул случайно ваш воздух? Извините, я так больше не буду.
+1
Не сотвори себе кумира, юный падаван, ибо великий грех гордыня есть, тебя на Темную сторону приведет она.
+1
Я подозреваю, что карма раздаётся нормальным распределением и в сумме, и для каждого в отдельности.

Гораздо интереснее не цифры в профиле (да и при 6 десятках выводы делать вообще рано), а то, что минусы в карму обычно схватываю там, где в каментах солидно наплюсили. Так что про 50% людей вывод очень куцый.
+9
всегда казалось что уж +tag то — это как раз — RFC — tools.ietf.org/html/rfc3696#section-3
и, нигде не сказано что + обязательно должен именно как алиас поддерживатся

по поводу резки поддоменов — … а как в общем случае быть уверенным что что user@vladivostok.domain.ru и user@domain.ru это один и тот же почтовый ящик? а если есть и user@moscow.domain.ru? а если там user@moscow.russia.domain.com?
+1
Именно так сделано у IBM, где ru.ibm.com совсем не равно us.ibm.com.
0
Для тех кто помнит: admin@mail.ru и admin@corp.mail.ru — не одно и то же, хотя это не всегда было так. =)
-1
Это только если $constraint->strict == true, в противном случае вступает в бой та самая регулярка, что я отметил.
+25
Если вы все-же хотите поддерживать RFC822, то для этого есть perl regex:
Не открывать
(?:(?:\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])*)?(?:[^()<>@,;:\\".\[\] \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])*)?(?:[^()<>@,;:\\".\[\] \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*(?:(?:[^()<>@,;:\\".\[\] \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
Регулярку точно писал человек? Не могу прочитать, из-за чего возникла необходимость такой вложенности…
+11
и? это уже другая проблема, к проверке email'a не относящаяся
0
К теме статьи напрямую не относится, но очень часто разработчики грешат тем, что «оптимизируют» экранирование, если уверены, что исходные данные чисты. E-mail или числа — как раз примеры таких данных, только вот и те, и другие могут быть проблемой (про e-mail уже написал, а числа могут быть отрицательными, т.е. -... и это иногда может быть дырой).

Поэтому совет проверки входной строки на простое наличие там @ я лично считаю опасным. В общем случае.
+5
Всякие поклонники Смарти, Django templates и т. п., конечно, со мной не согласятся… но, по моему мнению, шаблонизатор, который по умолчанию не эскейпит вывод, это полный треш. Проблемы @"><img просто не должно существовать. Надо заниматься бизнес-логикой, юзабилити, а про это просто не думать. Для меня полнейшая загадка, почему этого ещё не поняли после стольких XSS.
0
С этим целиком согласен, но даже в новомодном Laravel для PHP стандартный шаблонизатор использует синтаксис подобный Mustache/Handlebars, но заменив {{ }} на некранирующий вывод, а {{{ }}} — на экранированный.

Печально, да. Народ до сих пор в потёмках. Да что там далеко ходить — habrahabr.ru/post/222453/#comment_7576571
0
Согласен, про Django templates я неправ.

Видимо, сказалась моя к ним ненависть за то, что как-то меня заставили условие разворачивать по ДНФ, т. к. Django не поддерживают скобок в условиях.
+3
символы тэгов выкашиваются на более низком уровне для абсолютно всех форм и везде, где пользователь может хоть что-то ввести
+1
Как сказал ahmpro, это уже другая проблема. Такое экранировать при выводе, а не при вводе надо.
+55
Есть противоположное мнение. Которое, во-первых, не накладывает стописяттысяч странных и непредсказуемых ограничений на пользователей (тем самым, потенциально уменьшая конверсию, как подход в статье, явно придуманный программистами, заботящимися о себе, а не о пользователе), а во-вторых – занимает не целую статью, а порядка одного приложения. Да и в реализации, как ни странно, попроще будет.

Не проверяйте синтаксис почтового ящика вообще, а просто пошлите туда письмо и убедитесь, что оно было получено.
UFO landed and left these words here
0
И не одна:
habrahabr.ru/post/55820/
habrahabr.ru/post/175329
habrahabr.ru/post/175375/
Но, эта — лучшая. Она единственная, которая объясняет что плохо и почему.
Кроме того, важно, что она рассеивает ложное чувство уверенности, что адреса почты — это просто и предупреждает грабли, с которыми может столкнуться такой самоуверенный гражданин.
+1
Тоже лет 10 назад не удавалось зарегистрироваться на половине сайтов из-за того, что мой е-мейл начинался с цифры. (1xxxx@abc.com)
0
Интернационализированные Домены IDN
Насколько я помню, поддержки IDN в почте еще нет нигде. Вики говорит вот так:
Всё ещё недоступно в полном объёме применение международных доменных имен в электронной почте. Технический стандарт, благодаря которому это станет возможно, разрабатывается инженерной группой Интернета (IETF)

Gmail тут отличился: в то время как стандарт включает в себя точку как стандартный символ, Gmail не делает различий между адресами ящиков с точками и без.
Это же давно известно. Прекрасный способ фильтровать спам — делаем разные фильтры на письма с точками и без. В результате если везде светим адрес в виде «bla.bla», то если придет на «blabla» — 99% что спам :)
+2
> В результате если везде светим адрес в виде «bla.bla», то если придет на «blabla» — 99% что спам :)

А теперь может быть кто-то умный, прочитавший эту статью. А вы уже об этом не узнаете.
0
я пользую +spam для этих целей, но не всегда пропускает +, тогда юзаю точку. Но фильтр спама на гуглопочты и без этого справляется
+2
Точки поддерживаются только в Gmail но не поддерживаются в Google Apps.
В apps только символ плюса. Так ivan@domain.com и ivan+spam@domain.com являются одним ящиком. На месте уже можно разруливать метки встроенными фильтрами.
0
В apps можно настроить catch all адрес и фильтры в нем на любой вкус.
-13
А вот еще один корректный адрес, он создан из допустимых для ��дреса символов:


rambler так не думает

image
+8
Много кто так не думает:
Крупные e-mail провайдеры не разрешают использовать это примерно по тем же причинам; таким образом обычно достаточно дозволять буквы, цифры, точки, подчеркивания, дефисы, апострофы и плюсы.
0
Ну да, обычно на форумах вопрос «какое регулярное выражение использовать для почты» начинается с элегантного однострочного RE до огромного, в несколько абзацев монстра.
-1
до огромного, в несколько абзацев монстра

Как в Perl модуле для проверки адреса в соответствии с RFC-822, например.

Собственно, regexp:
(?:(?:\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*)
+16
Не нравятся конторы, которые запрещают «+» в почтовых адресах и пытаются блокировать одноразовые почтовые службы вроде mailinator.com

  1. Я всё равно не скажу им свою реальную почту: если бы хотел, сказал бы сразу.
  2. Я всё равно найду способ не давать им свой адрес.
  3. Если совсем ничего не получится, я уйду, не регистрируясь.

Борьба с необычными почтовыми адресами — это в чистом виде борьба с пользователями. Нафига пользоваться сайтом, который с тобой борется?
+6
Подобные конторы хотят на вас заработать и для этого им нужен хотя бы ваш адрес почты. То, что вы предоставите им фальшивый адрес, равносильно для них тому, что вы просто уйдёте. Поэтому подобными сайтами изначально не стоит пользоваться.
+2
Шок! Сенсация! Сайты хотят зарабатывать на пользователях :)
Не стоит ими пользоваться.
+1
Ну окай, тогда так: «не стоит пользоваться теми сайтами, что пытаются навязывать свои услуги».
Нормальные сайты не требуют регистрации даже при покупке на них чего-нибудь.
0
только сейчас вот пробовала зарегистрироватся с адресом вида vikarti+site@domain.com на сайте где для использования подразумевается плат��ая подписка. но видимо им деньги не нужны совсем и заработать на мне у них не получилось по причине собственной же лени в создании нормальной проверки.
-2
Я вот так делаю:
$email = "example@mail.com";
$apos = strrpos($email, '@');

if ($apos > 0 AND $apos < strlen($email) - 1) {
    print('Email ' . htmlspecialchars($email)  . ' is valid!');
}
else {
    print('Email ' . htmlspecialchars($email)  . ' is invalid!');
}
0
Чтобы лишний раз не отправлять запрос на сервер использую такую проверку:

/(.*)@(.{4,})$/

А чтобы не словить XSS на клиенте данные уже с сервера приходят заэнкоженнные.
0
var pair = email.split('@');
var valid = (pair.length == 2 && pair[0].length > 0 && pair[1].length > 0);
0
test подстроку проверяет, как я понял, а не всю строку. Я перед написанием того комментария абсолютно такой же код пробовал.
-2
Ну и? Если человек хочет ввести левый меил, то он его введет. И не важно, сколько собачек, запятых или точек будет в сообщении, оно ему никогда не придет, а у вас запись всё же останется.
0
Чтобы избежать ошибки, когда человек не в то поле ввел, например
0
Email @ is invalid!

Что-то в этом есть. Где бы зарегать?

Особенно радует, что $email = ""; — тоже валидный.
0
Портанул видимо криво, на js всё ок:
/**
var email = "example@mail.com";
var apos = email.lastIndexOf('@');

if (apos > 0 && apos < email.length - 1) {
    console.log('Email ' + email  + ' is valid!');
}
else {
    console.log('Email ' + email  + ' is invalid!');
}
*/

['example@mail.com', '@gmail.com', '@', 'example@', ''].forEach(function(email) {
	var apos = email.lastIndexOf('@');
	
	console.log('Email ' + email  + ' is '+((apos > 0 && apos < email.length - 1) ? '':'in')+'valid!');
});


log:
"Email example@mail.com is valid!"
"Email @gmail.com is invalid!"
"Email @ is invalid!"
"Email example@ is invalid!"
"Email  is invalid!"
+2
«Email @ is invalid!» — вот это валидный email по этой проверке.
+3
Минусовать собеседника — моветон.
js.do/dovg/38846
Email Email example@ is invalid! is valid!
Email Email example@ is invalid! is valid! — тоже кстати валидный email по вашей проверке.
-7
Вы статью читали? У вас емеил просто содержит пробелы, так что по этой проверке он валиден. Минус считаю заслуженным.
+2
Из-за таких мнений, что, регистрозависимость можно игнорировать и принудительно приводить имя ящика к нижнему регистру, в большом количестве случаев невозможно пользоваться ящиком на bitmessage-email гейте :-(
+2
Угу. Ещё умиляет мнение людей, которые читают RFC, а видят там фигу. Вот объясните мне, идиоту, откуда взялось мнение о регистронезавсимости адресов? RFC как бы говорит чётко и недвусмысленно: The local-part of a mailbox MUST BE treated as case sensitive. Therefore, SMTP implementations MUST take care to preserve the case of mailbox local-parts. In particular, for some hosts, the user "smith" is different from the user "Smith".
+1
Стандарт конечно допускает, но если локальная политика запрещает создание таких ящиков, то где здесь проблема? Это хорошая тактика против фишеров. Потому что сходу отлитичить smith@example.com и smIth@example.com (upper «i») в подписанном сообщении (т.е где визуально показано, что адрес легитимный) не представляется возможным.

Вообще статья про то, что стандарты должны адаптироваться со временем.
0
Проблема в том, что отправитель не может и не должен быть осведомлён о том, какая на сервере получателя локальная политика, посему регистр он обязан соблюдать.
0
Можно сохранять адрес e-mail «as is», но при проверке есть ли уже пользователь с данным e-mail, выполнять регистронезависимый поиск (т.к. в 99% случаев регистр действительно не имеет значения).
Ну и с точки зрения пользователя лучше использовать общепринятые стили адресов, а не искать самый экзотический вариант, валидный по RFC.
0
!#$%&'*+-/=?^_`{}|~example.com <== Корректный адрес вряд ли достойный поддержки


Тот, кто в своё время активно пользовался UUCP протоколом, смотрит на такие адреса с бооольшим недоверием.
+3
Добавлю, что доменное имя не обязательно должно содержать точку, что порой удобно при тестировании: user@localhost
0
а кстати, с вводом новых tld, вполне возможно отсутствие точки и в глобальном виде.
info@ibm
0
$emails = ['admin@host.com', 'admin.2@test.gov.com.net', 'путин@президент.рф', 'admin admin@host.com', '@host.com', 'test+next@123.123.123.123', '123312@', '@', 'admin@localhost', '!$%^*@host.com'];

foreach ($emails as $email) {
     $valid = filter_var($email, FILTER_VALIDATE_EMAIL);
     if ($valid) {
          echo "OK: '" . $email . "' is valid <br/>";
     } else {
          echo "ERROR: '" . $email . "' is invalid <br/>";
     }
}
/*
'admin@host.com' - OK
'admin.2@test.gov.com.net' - OK
'путин@президент.рф' - ERROR
'admin admin@host.com' - ERROR
'@host.com' - ERROR
'test+next@123.123.123.123' - ERROR
'123312@' - ERROR
'@' - ERROR
'admin@localhost' - ERROR
'!$%^*@host.com' - OK 
*/

Пользуюсь таким вариантов. В целом, сплю спокойно, хотя два последних варианта настораживают.
+1
А как юзать теги в адресе гугловской почты. Отправил письмо на ящик с тегом, оно пришло как обычное, никаких тегов в списке писем не появилось.
0
Фильтры настраивать надо. Если бы теги добавлялись автоматом — представляете, как можно ящик загадить? :)
+1
Товарищ автор!
Вот, на самом деле, такое же люди как вы, которые считают, что совсем не обязательно поддерживать RFC и достаточно только [a-z0-9.-] меня всё чаще и чаще огорчают тем, что либо нельзя зарегистрироваться на их сайте (плюс у них, видите ли, недопустимый символ для e-mail), либо e-mail просто тупо ВООБЩЕ не приходит, пока там есть экстеншн (да и сам плюс, скорее, всего, тоже).

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

Как-то так…
+4
Вы меня простите, уважаемый переводчик, но автор статьи является вредителем.

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


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

«Alan Turing»example.com <== Это корректно, но поддерживать не стоит


А апостроф стоит. Чем объяснсняется такая избирательность?

Кроме того, некоторые системы позволяют добавлять теги к адресу. Обычно это происходит в формате:
mailbox+tag@hostname

Было бы недурно перед тем, как воевать со стандартами, их почитать.

Никаких «тэгов» упомянутые 822/2822 не предусматривают. Знак плюс является ВАЛИДНЫМ символов в любом месте адресной части. Существуют другие RFC, которые описывают необязательный механизм адрсации одного ящика многими адесами, который сервера МОГУТ выбрать поддерживать. Опять же, нигде не сказано, что это непременно знак плюс.

Считайте, что имя почтового ящика регистронезависимо:
ALLEN@example.com
Allen@example.com
allen@example.com

Удачи при посылки почты, например, мне. Если регистр будет нарушен, мой сервер отвергнет письмо из-за неверного адресата, и мне пофиг, как это делают другие. Регистр ОБЯЗАН учитываться.

Gmail не делает различий между адресами ящиков с точками и без. Эти адреса указывают на один и тот же почтовый ящик:
first.last@gmail.com
firstlast@gmail.com
f.i.r.s.t.l.a.s.t@gmail.com

А не Gmail — делает различия. Кроме того, домены под Гугл Аппсом тоже не делают различий. Как будем выходить из ситуации?
Некоторые адреса содержат ненужные поддомены: например, «email.msn.com» и «msn.com» являются одним и тем же почтовым доменом

А некоторые не являются. Мой реальный адрес выглядит как name@subdomain.domain.lv, будете выкидывать первую часть или как?

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

Ставлю три бочки рома против дохлого попугая, что неприятности на вашу у вас будут как раз в том случае, если вы будете подвергать «каноникализации» то, что ввёл пользователь, и согласно своему разумению уродовать адреса, сравнивать, и принимать решения об их идентичности либо различности.

UUCP bang path, может, и впрямь экзотика, в первую очередь потому, что с высокой вероятностью сервер вашего провайдера не настроен на их роутинг, но трогать всё остальное, что не содержит знаков "!", это просто накликивать себе проблемы и лучи ненависти благодарных пользователей. DON'T DO IT.
+5
Считайте, что имя почтового ящика регистронезависимо:
ALLEN@example.com
Allen@example.com
allen@example.com


Удачи при посылки почты, например, мне. Если регистр будет нарушен, мой сервер отвергнет письмо из-за неверного адресата, и мне пофиг, как это делают другие. Регистр ОБЯЗАН учитываться.


По вашему мнению, публичные сервисы предоставляющие почту должны регистрировать Allen@example.com и allen@example.com как два разных аккаунта? Почему в таком случае в написании доменных имен регистр не учитывается, а в имени пользователя учитывается? Эта история яркий пример habrahabr.ru/post/224623/#comment_7642915 тому, что стандарт устарел и должен быть изменен.
-2
Мне все равно, что должны и не должны публичные сервисы почты. Я лишь утверждаю, что публичный сервис, который воспринимает почтовые адреса, ДОЛЖНЫ учитывать регистр именной части.

Почему в таком случае в написании доменных имен регистр не учитывается, а в имени пользователя учитывается?


Потому что именная часть контролируется RFC-2822, а доменная RFC-1034.

Когда стандарт изменится хотя бы в виде RFC proposal, тогда и обсудим. Пока же существуют как «Allen@», так и «allen@» в качестве различных адресов на одном сервере, одним чихом это не поменять.
+3
С таким отношением Вы рискуете, что в какой-то момент сможете писать письма только самому себе.

Где бы сейчас был веб если бы все ждали пока почешется W3C?
0
Такое отношение я исповедую последние 15 лет, и как-то пока плюсов заметно больше. Искажают адрес спамеры.
+2
«Разные адреса» не равносильно «разные пользователи». Это дело конкретного почтового сервера конкретной организации, привязывать ли разные адреса, отличающиеся регистром к одному и тому же пользователю или нет. А приложение или веб-сервис не должно считать, что оно лучше пользователя знает, какой у него email и как-то его искажать.
+5
Вот, кстати, про регистрозависимость могу небольшую сказку рассказать.

Жил да был старик Ростом. Хорошо старик жил, в свои 87 успешно пользовался компьютером, ходил по садам зелёным (он каждые выходные приезжал в свой загородный дом на старой советской Волге), писал музыку и ходил собирать грибы. И тут Ростом решил сайт свой сделать. Ну, — думает старик, — дело-то простое, благо, Django ещё года 4 назад выучил. Сверстал всё Ростом, провёл UX-испытания, потом нарисовал прототип ещё более удачного интерфейса, снова за вёрстку принялся, потом сел за программирование бэкэнда, потом JS стал писать. В общем, так месяца два прошло, и в итоге сайт был готов. Два дня он с друзьями событие это светлое отмечал! Компания подобралась хорошая, громкая. Вино пили, песни пели, на гитаре играли. А на сайте тем временем уже где-то полтысячи пользователей зарегистрировалось. И тут стал у Ростома в кармане айфон пищать — сообщения на email приходят. Смотрит Ростом, а это пользователи пишут. Говорят, что не могут на сайт войти.

Стал Ростом думать и гадать, сайт тестировать, и никак не поймёт, в чем дело. С виду — всё работает! Уж было хотел на Тостер иль Stackoverflow вопрос писать, и тут понимает: это так бэкэнд авторизации работает! Пользователь регистрировался с адресом Superkitty@yandex.ru, а вводит при логине superkitty@yandex.ru. Одна лишь буква в другом регистре, но этого достаточно, чтобы сайт считал, что это почтовый адрес другого пользователя.

И написал тогда Ростом свой бэкэнд авторизации.
from django.contrib.auth.backends import ModelBackend
from django.contrib.admin.models import User

class EmailAuthBackend(ModelBackend):
    def authenticate(self, email=None, password=None, **kwargs):
        if not email:
            return None

        try:
            user = User.objects.get(email__iexact=email)  
        except User.DoesNotExist:
            return None
        except User.MultipleObjectsReturned:
            user = User.objects.filter(email__iexact=email)[0]

        if user.check_password(password):
            return user

И ответил пользователю — попросил его попробовать ещё разок. Пользователь попробовал, и у него всё получилось. Вот так вот старик Ростом хоть и убавил соответствия стандартам, но зато позволил большему количеству простых людей иметь меньше заморочек с его сайтом, потому что после этой правки они смогли вводить свой почтовый адрес в любом регистре — и сайт при этом всегда встречал их открытыми дверьми и тёплыми приветствиями.

Вот и сказочке конец, а кто слушал — молодец.
0
Непонятно, почему это для логина на сайте должны действовать такие же стандарты, как для адресов почты.
Ничего нет страшного в том, чтобы адрес сохранять и использовать только в том же регистре, как ввёл его пользователь, а логиниться разрешать с любым регистром.
0
Ну, гипотетически, сайт таким образом ущемляет других пользователей с тем же адресом, в котором какие-то символы набраны в другом регистре (потому что среди пользователей, адрес которых отличается только регистром символов, сможет зарегистрироваться только первый). Но, как говорится, special cases aren’t special enough to break the rules: в данном случае можно вполне обоснованно принять позицию, в соответствии с которой такие пользователи ССЗБ, и должны использовать другую почту, если сайт им всё-таки нужен.
0
Итак, вам вероятно следует воздержаться от поддержки адреса, если он содержит:
***
Специальные символы кроме '._+-
***

Вот тут не соглашусь! У одного меня полно знакомых с ящиками, где есть спецсимволы. Особенно часто: _ и -
+16
Страница ада для моего ника. Столько нотификаций я не получал никогда.
+5
Шел 2014 год, а программисты все спорили как проверять валидность email.
Only those users with full accounts are able to leave comments., please.