Как правильно проверить email на валидность в JavaScript с помощью регулярных выражений?
Почему сложно (и не нужно) писать идеальный regex для email
Спецификация RFC 5322 определяет очень сложный формат email-адресов, который включает комментарии, кавычки, экранирование и многое другое. На практике для клиентской валидации достаточно базовой проверки, а полную верификацию лучше доверить серверу (отправка письма с подтверждением).
Правильный подход: минимальная проверка на клиенте
Лучшая практика — использовать простое регулярное выражение, которое отсеивает очевидно неверные адреса, но не пытается покрыть все краевые случаи. Вот рекомендованный вариант:
function isValidEmail(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
Как это работает
^— начало строки[^\s@]+— один или более символов, которые не являются пробелом и не являются @ (локальная часть)@— обязательный символ @[^\s@]+— доменное имя (без пробелов и @)\.— точка (экранированная)[^\s@]+— домен верхнего уровня (например, .com, .ru)$— конец строки
Этот regex гарантирует:
- Наличие символа @
- Наличие точки после домена
- Отсутствие пробелов
- Наличие хотя бы одного символа до @, между @ и точкой, и после точки
Примеры работы
console.log(isValidEmail("user@example.com")); // true
console.log(isValidEmail("test@.com")); // false (пусто между @ и .)
console.log(isValidEmail("user@domain")); // false (нет точки)
console.log(isValidEmail("a@b.c")); // true (формально валидно)
console.log(isValidEmail("user name@example.com")); // false (пробел)
console.log(isValidEmail("")); // false
Почему не стоит усложнять?
Более строгие регулярные выражения (например, проверяющие допустимые символы в локальной части) могут быть слишком длинными, трудными для поддержки и всё равно не гарантируют, что адрес реально существует. Например, test@test.test пройдёт любую клиентскую проверку, но домен .test не существует в реальности.
Рекомендация для реального проекта
Используйте встроенную валидацию HTML5 с атрибутом type="email" в теге <input>. Она достаточно хороша для 99% случаев:
<input type="email" required>
Если нужно кастомное сообщение об ошибке, добавьте обработчик события:
document.querySelector('input[type="email"]').addEventListener('input', function(e) {
const errorSpan = document.getElementById('email-error');
if (this.validity.typeMismatch || this.validity.valueMissing) {
errorSpan.textContent = 'Пожалуйста, введите корректный email';
} else {
errorSpan.textContent = '';
}
});
Помните: клиентская валидация — для удобства пользователя, серверная — для безопасности. Никогда не доверяйте данным, которые пришли с клиента, даже если они прошли проверку на JavaScript.
<<Альтернативный подход: валидация через input с type="email"
В современных браузерах можно вообще обойтись без регулярных выражений, используя встроенную валидацию HTML5. Это самый простой и надёжный способ для базовой проверки:
<form id="myForm">
<input type="email" id="emailInput" required>
<button type="submit">Отправить</button>
</form>
<script>
document.getElementById('myForm').addEventListener('submit', function(e) {
const emailInput = document.getElementById('emailInput');
if (!emailInput.checkValidity()) {
e.preventDefault();
alert('Пожалуйста, введите корректный email');
}
});
</script>
Метод checkValidity() проверяет поле согласно встроенным правилам браузера для type="email". Он учитывает большинство распространённых ошибок: отсутствие @, отсутствие домена, недопустимые символы и т.д.
Если вам нужно больше контроля (например, запретить адреса с однобуквенным доменом вроде a@b.c), можно комбинировать HTML5-валидацию с дополнительной проверкой через регулярное выражение:
const email = emailInput.value;
const customRegex = /^[^\s@]+@[^\s@]+\.[a-zA-Z]{2,}$/;
if (!customRegex.test(email)) {
// показываем ошибку
}
Этот подход даёт и простоту реализации, и гибкость для кастомных правил.
Ответов пока нет.
Войдите чтобы оставить ответ