Комментарии 103
Вообще всегда были подозрительны люди в яшиками не в формате imyafamiliya334356@mail.ru
Вообще всегда были подозрительны люди в яшиками не в формате imyafamiliya334356@mail.ru
У людей просто нет фантазии, а все нормальные ники заняты )
Гораздо интереснее не цифры в профиле (да и при 6 десятках выводы делать вообще рано), а то, что минусы в карму обычно схватываю там, где в каментах солидно наплюсили. Так что про 50% людей вывод очень куцый.
и, нигде не сказано что + обязательно должен именно как алиас поддерживатся
по поводу резки поддоменов — … а как в общем случае быть уверенным что что user@vladivostok.domain.ru и user@domain.ru это один и тот же почтовый ящик? а если есть и user@moscow.domain.ru? а если там user@moscow.russia.domain.com?
github.com/symfony/Validator/blob/master/Constraints/EmailValidator.php#L66
if ($constraint->strict && class_exists('\Egulias\EmailValidator\EmailValidator')) {
$strictValidator = new StrictEmailValidator();
$valid = $strictValidator->isValid($value, false);
github.com/egulias/EmailValidator
(?:(?:\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*)
http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html
email.match /@/
Вместо тысячи слов
@"><img/src="//owned
-...
и это иногда может быть дырой).Поэтому совет проверки входной строки на простое наличие там
@
я лично считаю опасным. В общем случае.{{ }}
на некранирующий вывод, а {{{ }}}
— на экранированный. Печально, да. Народ до сих пор в потёмках. Да что там далеко ходить — habrahabr.ru/post/222453/#comment_7576571
Не проверяйте синтаксис почтового ящика вообще, а просто пошлите туда письмо и убедитесь, что оно было получено.
habrahabr.ru/post/55820/
habrahabr.ru/post/175329
habrahabr.ru/post/175375/
Но, эта — лучшая. Она единственная, которая объясняет что плохо и почему.
Кроме того, важно, что она рассеивает ложное чувство уверенности, что адреса почты — это просто и предупреждает грабли, с которыми может столкнуться такой самоуверенный гражданин.
Интернационализированные Домены IDNНасколько я помню, поддержки IDN в почте еще нет нигде. Вики говорит вот так:
Всё ещё недоступно в полном объёме применение международных доменных имен в электронной почте. Технический стандарт, благодаря которому это станет возможно, разрабатывается инженерной группой Интернета (IETF)
Gmail тут отличился: в то время как стандарт включает в себя точку как стандартный символ, Gmail не делает различий между адресами ящиков с точками и без.Это же давно известно. Прекрасный способ фильтровать спам — делаем разные фильтры на письма с точками и без. В результате если везде светим адрес в виде «bla.bla», то если придет на «blabla» — 99% что спам :)
В apps только символ плюса. Так ivan@domain.com и ivan+spam@domain.com являются одним ящиком. На месте уже можно разруливать метки встроенными фильтрами.
А вот еще один корректный адрес, он создан из допустимых для адреса символов:
rambler так не думает
Крупные e-mail провайдеры не разрешают использовать это примерно по тем же причинам; таким образом обычно достаточно дозволять буквы, цифры, точки, подчеркивания, дефисы, апострофы и плюсы.
до огромного, в несколько абзацев монстра
Как в Perl модуле для проверки адреса в соответствии с RFC-822, например.
(?:(?:\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*)
- Я всё равно не скажу им свою реальную почту: если бы хотел, сказал бы сразу.
- Я всё равно найду способ не давать им свой адрес.
- Если совсем ничего не получится, я уйду, не регистрируясь.
Борьба с необычными почтовыми адресами — это в чистом виде борьба с пользователями. Нафига пользоваться сайтом, который с тобой борется?
Не стоит ими пользоваться.
$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!');
}
/(.*)@(.{4,})$/
А чтобы не словить XSS на клиенте данные уже с сервера приходят заэнкоженнные.
Email @ is invalid!
Что-то в этом есть. Где бы зарегать?
Особенно радует, что $email = ""; — тоже валидный.
/**
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!"
js.do/dovg/38846
Email Email example@ is invalid! is valid!
Email Email example@ is invalid! is valid! — тоже кстати валидный email по вашей проверке.
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
".Вообще статья про то, что стандарты должны адаптироваться со временем.
Ну и с точки зрения пользователя лучше использовать общепринятые стили адресов, а не искать самый экзотический вариант, валидный по RFC.
user@localhost
$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
*/
Пользуюсь таким вариантов. В целом, сплю спокойно, хотя два последних варианта настораживают.
Вот, на самом деле, такое же люди как вы, которые считают, что совсем не обязательно поддерживать RFC и достаточно только [a-z0-9.-] меня всё чаще и чаще огорчают тем, что либо нельзя зарегистрироваться на их сайте (плюс у них, видите ли, недопустимый символ для e-mail), либо e-mail просто тупо ВООБЩЕ не приходит, пока там есть экстеншн (да и сам плюс, скорее, всего, тоже).
В общем, чтобы не было разночтений «почему эти куски RFC можно не поддерживать, а эти — нельзя» я таки предлагаю поддерживать RFC полностью.
Как-то так…
Бывает еще смешнее.
На госуслугах у пользователя email с + (разумеется проверка через отправку проверочного сообщения — пройдена).
У банка есть вариант взять данные с госуслуг при заполнении заявки и в этом случае те поля что взяты насколько помню редактировать нельзя.
Вот только банк все равно проверяет e-mail, и не допускает +, форма выкидывает ошибку.
С точки зрения банка — виноват кто угодно кроме них.
Несмотря на то, что этот совет может показаться слишком радикальным, это все равно лучше, чем слепо подчиняться стандартам.
Замечательный, глубокий совет. Зачем слепо подчинятся, когда можно подойти творчески!
«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.
Считайте, что имя почтового ящика регистронезависимо:
ALLEN@example.com
Allen@example.com
allen@example.com
Удачи при посылки почты, например, мне. Если регистр будет нарушен, мой сервер отвергнет письмо из-за неверного адресата, и мне пофиг, как это делают другие. Регистр ОБЯЗАН учитываться.
По вашему мнению, публичные сервисы предоставляющие почту должны регистрировать Allen@example.com и allen@example.com как два разных аккаунта? Почему в таком случае в написании доменных имен регистр не учитывается, а в имени пользователя учитывается? Эта история яркий пример habrahabr.ru/post/224623/#comment_7642915 тому, что стандарт устарел и должен быть изменен.
Почему в таком случае в написании доменных имен регистр не учитывается, а в имени пользователя учитывается?
Потому что именная часть контролируется RFC-2822, а доменная RFC-1034.
Когда стандарт изменится хотя бы в виде RFC proposal, тогда и обсудим. Пока же существуют как «Allen@», так и «allen@» в качестве различных адресов на одном сервере, одним чихом это не поменять.
Жил да был старик Ростом. Хорошо старик жил, в свои 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
И ответил пользователю — попросил его попробовать ещё разок. Пользователь попробовал, и у него всё получилось. Вот так вот старик Ростом хоть и убавил соответствия стандартам, но зато позволил большему количеству простых людей иметь меньше заморочек с его сайтом, потому что после этой правки они смогли вводить свой почтовый адрес в любом регистре — и сайт при этом всегда встречал их открытыми дверьми и тёплыми приветствиями.
Вот и сказочке конец, а кто слушал — молодец.
Ничего нет страшного в том, чтобы адрес сохранять и использовать только в том же регистре, как ввёл его пользователь, а логиниться разрешать с любым регистром.
Итак, вам вероятно следует воздержаться от поддержки адреса, если он содержит:
***
Специальные символы кроме '._+-
***
Вот тут не соглашусь! У одного меня полно знакомых с ящиками, где есть спецсимволы. Особенно часто: _ и -
Шел 2022 и некоторые программисты считают что если есть
личность A с e-mail'ом <Имя>.<Фамилия>@gmail.com (которая НЕ клиент сервиса O)
и личность B с e-mail'ом <имяфамилия>@gmail.com (которая клиент)
То A обязана получать информацю об заказах и прочем личности B
При этом техподдержка сервиса О то считает что это проблемы личности A и оная личность должна поменять себе e-mail. Ну или написать в гугл. При этом у сервиса есть обязательное указание телефона и они имеют вход через SMS.
Вообще такая трактовка имён аккаунтов как одинаковых внедрена гуглом: регистр букв и любое количество точек в любых местах не имеют значения и игнорируются. Т.е. указанные Вами адреса - это действительно один email. Равно как и Имя.Фам.Или.Я@gmail.com. Так что техподдержка ответила абсолютно корректно.
Никогда не проверяйте e-mail адреса по стандартам RFC