Последнее обновление:
Регулярное выражение для проверки правильности написания адреса e-mail
При отправке сообщения пользователя через форму обратной связи на сайте зачастую требуется провести проверку правильности адреса электронной почты (e-mail), который был указан пользователем. Это целесообразно, как минимум, по двум причинам:
- Чтобы пользователь по ошибке не указал неверный (точнее, не соответствующий требуемому шаблону) электронный адрес
- Чтобы на сервер (в соответствующую переменную) не попадали подозрительные символы, например, <, > или &.
Отметим, что, на самом деле, актуальность такой проверки находится под вопросом, что и подтверждается спорами на форумах в интернете. Тем более, что даже если пользователь введет корректный, с точки зрения шаблона, адрес e-mail, он может оказаться попросту несуществующим.
Проверку удобно производить при помощи регулярных выражений. Потому, что это, например, если использовать РНР, быстрое средство проверки, в отличие от варианта, когда алгоритм ее программируется самостоятельно.
Почему? Потому, что аппарат регулярных выражений выполнен на языках С/С++, а не на РНР (Python, Java или иных подобных языках).
На самом деле, на сайтах есть немало разновидностей подобных регулярных выражений – и все зависит от потребностей проверки. Поставим задачу. В состав электронного адреса:
- Могут входить латинские буквы, цифры, а также некоторые символы (например, плюс, минус, нижнее подчеркивание, точка и @);
- Не могут входить две точки, расположенные подряд;
- Должен входить символ @ один и только один раз;
- Должна входить последняя часть (домен первого уровня), содержащая не менее 2 символов.
Перечисленным требованиям соответствует следующее регулярное выражение:
"/^[_a-z0-9-\+-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/i"
Оно является полностью рабочим. Использование его в РНР может быть примерно следующим:
preg_match("/^[_a-z0-9-\+-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/i", $e_mail)
Эта функция вернет true, если переменная $e_mail соответствует указанному шаблону, false – если нет.
Рассмотрим устройство регулярного выражения для e-mail
Нередко регулярные выражения вызывают трудности даже не у начинающих программистов – в силу их «особенного» синтаксиса. Поэтому разберем полностью это выражение. Запись
[_a-z0-9-
\+
-]
означает, что в начале (по крайней мере, первый его символ) электронного адреса могут находиться латинские буквы, цифры, знак подчеркивания, плюс, минус.
Так как знак «+» относится к специальным символам, он экранируется обратным слэшем «\». Знак минус «-» тоже является специальным символом, но, так как он находится в самом конце конструкции [ ] , то экранировать его не нужно.
Обозначение [_a-z0-9-
\+
-]
означает, что в начальной части электронного адреса могут быть использованы любые символы из перечисленных в квадратных скобках.
Знак «+» после [_a-z0-9-
\+
-]
означает, что указанные к квадратных скобках символы могут содержаться 1 или более раз (т.е., как минимум, один раз).
Совокупность a-z означает, что могут использоваться символы в диапазоне от a до z, т.е. все латинские буквы. Аналогично, совокупность 0-9
означает, что могут использоваться любая арабская цифра (т.е. от 0 до 9).
Итак, начальная часть адреса электронной почты может выглядеть, например, так:ahjfd
-485
a+aj_f966_80
ggjjj4kg-_rr_
Ну, и т.д.
Важно, что указанный шаблон НЕ допускает наличие, например, пробелов (которые могут нажиматься пользователями при вводе электронного адреса по недосмотру).
Шаблон группы (
\.
[_a-z0-9-]+)
означает, что в ее состав могут входить латинские буквы, цифры, знак «-», а также точка. Причем, точка может идти лишь в начале и может быть лишь одна, тогда как латинских букв и/или цифр – теоретически, сколько угодно.
Кстати, так как точка относится к специальным символам, она экранируется обратным слэшем.
Символ *, идущий после этой группы, означает, что она может быть повторена 0 или более раз (т.е. может вообще отсутствовать или повторяться, по сути, неограниченное количество раз). Ну, а далее идет всем известный символ @.
С учетом этого, часть электронного адреса, расположенная до @, может иметь такой вид:
a+aj_f966_80.fjgfg-.565.ee
revtrv.++.5tt
Обратим внимание, что:
- эта часть не может, в частности, оканчиваться на точку;
- символ @ может содержаться только один единственный раз;
- если бы мы включили точку в состав [_a-z0-9-\+-], получилось бы, что точка могла бы дублироваться наравне с иными разрешенными символами, что недопустимо.
То, что идет после @
Там может быть примерно то же, что а до него. Иными словами, корректными будут следующие электронные адреса:
a+aj_f966_80.fjgfg-.565.ee@gjgf.6.665
revtrv.++.5tt@f.-
Последняя часть адреса электронной почты обязательно должна включать в себя домен:
(
\.[a-z]{2,})
Видим, что домен может состоять только из латинских букв. Символы {2,} означают, что количество символов в обозначении домена должно быть не менее 2. Т.е. это все известные на сегодняшний день домены: ru, com, online и др. Однобуквенных или цифровых доменов пока, вроде бы, нет.
Отдельно следует обратить внимание на символы ^ и $
Эти символы обозначают начало и конец строки, соответственно (кстати, во многих шаблонах для e-mail, которые доводилось увидеть на сайтах, эти символы отсутствовали, что совершенно напрасно). Дело в том, что когда регулярное выражение заключено в эти символы, стало быть, проверяться на предмет соответствия ему будет ВСЯ строка. Иначе говоря, ВСЯ строка (а не ее какая-либо часть) должна совпадать с шаблоном.
Если не указать символы ^
и $
, то, например, такая строка, как
bvgrbgr xxx@mail.ru?tvbvnj##@%&* привет»!
будет вполне удовлетворять шаблону, так как содержит в себе корректный электронный адрес xxx@mail.ru. При отсутствии символов ^, $ может проверяться не только вся строка, но и любая ее часть.
Идентификатор, заставляющий игнорировать регистр
Идентификатор i , приведенный в конце регулярного выражения, необходим для того, чтобы игнорировались различия между регистрами букв (т.е. различия между строчными и заглавными буквами, например, между а и А). Ведь пользователь может ввести электронный адрес как в нижнем, так и в верхнем регистре.
Во многих почтовых системах разница между символами в разных регистрах отсутствует. Например, адреса 1@Rambler.ru и 1@rambler.ru будут считаться эквивалентными. Тем не менее, пользователь может использовать разные регистры хотя бы по причине того, что включена соответствующая раскладка клавиатуры и он не желает тратить время на ее изменение.
Если на компьютере все просто и сводится к (не)использованию клавиш Caps Lock
и Shift
(а это – дело 1 секунды), то, например, на телефонах – несколько сложнее: придется заходить в соответствующее меню и там выбирать раскладку.
Кавычки и слеши
Использование кавычек в регулярном выражении полагается по стандарту во многих языках. В них содержится все регулярное выражение, включая его идентификатор.
Что касается обратных слешей «/», то надо сказать, что они являются ограничителями, т.е. содержат в себе тело регулярного выражения (без идентификаторов). Именно обратные слеши работают в подавляющем большинстве языков программирования, поддерживающих регулярные выражения.
Однако, разные языки содержат в себе, в общем случае, разные символы, которыми могут ограничиваться регулярные выражения. Скажем, в javascript используются слеши и только слеши. И вот в РНР, помимо них, согласно стандарта PCRE, возможно также использование таких символов-ограничителей, как [ ], ! !
, # #
, ' '
, { }
, ( )
. Например, следующие регулярные выражения в языке PHP будут являться одинаковыми:
"/[a-z]{2,}/i"
(универсальный формат)
"[[a-z]{2,}]i"
'"[a-z]{2,}"i'
"'[a-z]{2,}'i"
"![a-z]{2,}!i"
'([a-z]{2,})i'
Тогда как в javascript (по крайней мере, на момент написания этой статьи, 2017 г.) применим только первый вариант.
Многие вебпрограммисты предпочитают пользоваться первым вариантом с обратными слешами - символами «/» по той причине, что так – привычнее, и чтобы не было путаницы; ведь многим из них приходится программировать как для клиента (на javascript), так и для сервера (к примеру, на РНР).
Обратите внимание, что ВНУТРИ регулярного выражения символы [ ]
, ( )
и т.д. имеют совсем иные смысл и действие.