Валидация имейлов
Валидный имейл — это существующий, реальный имейл, на который можно отправить письмо. Задача программиста — создать валидацию имейла, т.е. проверку программой имейла на валидность. Задача тестировщика — проверить то, как программа валидирует имейлы, правильно ли она это делает.
Перед тем как писать валидацию, надо знать из чего состоит email адрес. Думаю известно всем что это «username@hostname».
Имя пользователя может в себе содержать:
-
- латиницу
-
- цифры
-
- знаки! # $ % & ‘ * + — / =? ^ _ ` { | } ~
- точку, за исключением первого и последнего знака, которая не может повторятся
Имя хоста состоит из нескольких компонентов, разделённых точкой и не превышающих 63 символа, и суффиксов (домены первого уровня). Компоненты, в свою очередь, состоят из латинских букв, цифр и дефисов, причём дефисы не могут быть в начале или в конце компонента. Суффиксы это ограниченный список доменов первого уровня.
Чит-лист для проверки поля email
1) Пустое поле email -> Сообщение о незаполненном поле email
2) Email в нижнем регистре -> Операция проводится успешно
3) Email в верхнем регистре -> Операция проводится успешно
4) Email с цифрами в имени аккаунта -> Операция проводится успешно
5) Email с цифрами в доменной части -> Операция проводится успешно
6) Email с дефисом в имени аккаунта -> Операция проводится успешно
7) Email с дефисом в доменной части -> Операция проводится успешно
Email со знаком подчеркивания в имени аккаунта -> Операция проводится успешно
9) Email со знаком подчеркивания в доменной части -> Операция проводится успешно
10) Email с точками в имени аккаунта -> Операция проводится успешно
11) Email с несколькими точками в доменной части -> Операция проводится успешно
12) Email без точек в доменной части -> Должно появится сообщение о неправильном или некорректном e-mail введеном в поле
13) Превышение длины email (>320 символов) -> Должно появится сообщение о неправильном или некорректном e-mail введеном в поле
14) Отсутствие @ в email -> Должно появится сообщение о неправильном или некорректном e-mail введеном в поле
15) Email с пробелами в имени аккаунта -> Должно появится сообщение о неправильном или некорректном e-mail введеном в поле
16) Email с пробелами в доменной части -> Должно появится сообщение о неправильном или некорректном e-mail введеном в поле
17) Email без имени аккаунта -> Должно появится сообщение о неправильном или некорректном e-mail введеном в поле
18) Email без доменной части -> Должно появится сообщение о неправильном или некорректном e-mail введеном в поле
19) Некорректный домен первого уровня (допустимо 2-63 букв после точки: .ru или например .americanexpress) ->Должно появится сообщение о неправильном или некорректном e-mail введеном в поле
Вообще по доменным именам нужна отдельная статья, но оставим здесь интересую информацию.
Например домен:
- zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz.ru — САмый последний домен в зоне ру.
llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch.info
— название деревни Лланвайр-Пуллгвингилл в Уэльсе на острове Англси, означающее «Церковь Святой Марии в ложбине, заросшей белым орешником, около быстрого водоворота, неподалёку от церкви Святого Тисилио и красной пещеры».
Базовые валидационные проверки Login/Password
- Заполнить поле корректный login и корректный pass. Expected: успешно залогинен. Разлогиниться. Почистить кэш и куки (открыть/закрыть браузер?).
- Оставить оба поля пустыми. Попытка входа. Expected: Сообщение об ошибке.
- Оставить пустое поле login. Попытка входа. Expected: Сообщение об ошибке.
- Оставить пустое поле password. Попытка входа. Expected: Сообщение об ошибке.
- Ввeсти корректный login и некорректный pass. Expected: Сообщение об ошибке.
- Ввeсти некорректный login, но корректный pass. Expected: Сообщение об ошибке.
- Ввeсти некорректный login и некорректный pass. Expected: Сообщение об ошибке.
- Заполнить поле login ввeсти корректный pass, а в поле пароля ввести корректный login. Expected: Сообщение об ошибке.
- Ввeсти login <script>alert(123)</script> и корректный pass. Expected: Сообщение об ошибке.
- Заполнить поле login SQL запрос (‘ or ‘a’ = ‘a’; DROP TABLE user; SELECT * FROM blog WHERE code LIKE ‘a%’;) — структура запроса зависит от DB.
- Заполнить поле login скрипт (<script>alert(“Hello, world!”)</alert>, <script>document.getElementByID(“…”).disabled=true</script>)
- Заполнить поле login html-теги (<form action=”http://live.hh.ru”><input type=”submit”></form>)
- Заполнить поле login сложную последовательность символов вроде “♣♂” , “”‘~!@#$%^&*()?>,./<][ /*<!–“”, “${code}”;–>
- Заполнить поле login текст состоящий из одних пробелов;
- Заполнить поле login правильный login, начинающийся с нескольких пробелов, и правильный pass. Expected: Сообщение об ошибке или автоматическое обрезание пробелов.
- Заполнить полеlogin правильный login, после которого следуют нескольких пробелов, и правильный pass. Expected: Сообщение об ошибке или автоматическое обрезание пробелов.
- Ввeсти корректный login и корректный pass. Нажать на кнопку “Назад” в браузере. Expected: или The page should be expired, или увидеть те же поля. Если второе – ввести в поля снова login и pass. Перейти. Залогинен?
- Ввeсти корректный login. Указать pass с использованием букв РАЗНОГО регистра.
- Ввeсти login с использованием букв РАЗНОГО регистра. Указать корректный pass.
- Проверить ограничение на длину login и пароля при регистрации? Ввести qqweqweqweqweqweqweqweqweqweqweqweqweqweqwe / qqweqweqweqweqweqweqweqweqweqweqweqweqweqwe
- Заполнить поле login/pass Aa!@#$%^&*()-_+=`~/,.?><|b / PaSSword!@#$%^&*()-_+=`~/,.?><| Есть ли ограничения на допустимые символы?
- Открыть первый бразуер. Залогиниться валидным юзером. Открыть второй браузер. Залогиниться тем же самым валидным юзером. Разлогиниться в первом браузере. Перейти во второй браузер. Сделать что-нибудь, что может сделать только залогиненный юзер.
- Открыть браузер. Ввести в поля валидные данные. Нажать на кнопку Login. Отключить интернет. Получить “страница недоступна”. Подключить интернет обратно. Зайти на сайт. Expected: не залогинен.
- Блокируется ли акаунт/IP того, кто введет n-количество раз не правильный pass?
- Установить фокус на поле login. Ввести текст. Нажать кнопку Tab на клавиатуре. Expected: фокус перемещается на поле пароля. Ввести текст. Нажать кнопку Tab на клавиатуре. Expected: фокус перемещается на галочку “remember me”. Нажать кнопку Space на клавиатуре. Expected: появилась галочка. Нажать кнопку Tab на клавиатуре. Expected: фокус перемещается на кнопку Login. Нажать кнопку Enter на клавиатуре. Expected: процесс пошёл.
- Проверка на ‘Remember me on this computer’. Заполнить поля валидными данными. Чекнуть галочку Remember me. Залогиниться. Закрыть браузер. Открыть бразуер. Открыть страницу сайта. Expected: login для входа не требуется.
- Ввeсти корректный login и корректный pass. Скопировать полученный url и вставить его в другой браузер. Expected: It should not display the user’s welcome page.
I believe in QA, все о тестировании
Using regular expressions is probably the best way of validating an email address in JavaScript. View a bunch of tests on JSFiddle taken from Chromium.
const validateEmail = (email) => {
return String(email)
.toLowerCase()
.match(
/^(([^<>()[]\.,;:s@"]+(.[^<>()[]\.,;:s@"]+)*)|.(".+"))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9]+.)+[a-zA-Z]{2,}))$/
);
};
The following is an example of a regular expression that accepts unicode.
const re =
/^(([^<>()[].,;:s@"]+(.[^<>()[].,;:s@"]+)*)|(".+"))@(([^<>()[].,;:s@"]+.)+[^<>()[].,;:s@"]{2,})$/i;
Keep in mind that one should not rely on JavaScript validation alone, as JavaScript can be easily disabled by the client. Furthermore, it is important to validated on the server side.
The following snippet of code is an example of JavaScript validating an email address on the client side.
const validateEmail = (email) => {
return email.match(
/^(([^<>()[]\.,;:s@"]+(.[^<>()[]\.,;:s@"]+)*)|(".+"))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9]+.)+[a-zA-Z]{2,}))$/
);
};
const validate = () => {
const $result = $('#result');
const email = $('#email').val();
$result.text('');
if(validateEmail(email)){
$result.text(email + ' is valid.');
$result.css('color', 'green');
} else{
$result.text(email + ' is invalid.');
$result.css('color', 'red');
}
return false;
}
$('#email').on('input', validate);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="email">Enter email address</label>
<input id="email" type="email">
<p id="result"></p>
10
I’ve slightly modified Jaymon’s answer for people who want really simple validation in the form of:
anystring@anystring.anystring
The regular expression:
/^S+@S+.S+$/
To prevent matching multiple @ signs:
/^[^s@]+@[^s@]+.[^s@]+$/
The above regexes match the whole string, remove the leading and ^
and trailing $
if you want to match anywhere in the string. The example below matches anywhere in the string.
If you do want to match the whole sring, you may want to trim()
the string first.
Example JavaScript function:
function validateEmail(email) {
var re = /S+@S+.S+/;
return re.test(email);
}
console.log(validateEmail('my email is anystring@anystring.any')); // true
console.log(validateEmail('my email is anystring@anystring .any')); // false
8
Just for completeness, here you have another RFC 2822 compliant regex
The official standard is known as RFC 2822. It describes the syntax that valid email addresses must adhere to. You can (but you shouldn’t — read on) implement it with this regular expression:
(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[x01-x08x0bx0cx0e-x1fx21x23-x5bx5d-x7f]|\[x01-x09x0bx0cx0e-x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[x01-x08x0bx0cx0e-x1fx21-x5ax53-x7f]|\[x01-x09x0bx0cx0e-x7f])+)])
(…) We get a more practical implementation of RFC 2822 if we omit the syntax using double quotes and square brackets. It will still match 99.99% of all email addresses in actual use today.
[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?
A further change you could make is to allow any two-letter country code top level domain, and only specific generic top level domains. This regex filters dummy email addresses like
asdf@adsf.adsf
. You will need to update it as new top-level domains are added.
[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?.)+(?:[A-Z]{2}|com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum)b
So even when following official standards, there are still trade-offs to be made. Don’t blindly copy regular expressions from online libraries or discussion forums. Always test them on your own data and with your own applications.
Emphasis mine
5
Wow, there are lots of complexity here. If all you want to do is just catch the most obvious syntax errors, I would do something like this:
^S+@S+$
It usually catches the most obvious errors that the user makes and assures that the form is mostly right, which is what JavaScript validation is all about.
EDIT:
We can also check for ‘.’ in the email using
/^S+@S+.S+$/
4
There’s something you have to understand the second you decide to use a regular expression to validate emails: It’s probably not a good idea. Once you have come to terms with that, there are many implementations out there that can get you halfway there, this article sums them up nicely.
In short, however, the only way to be absolutely, positively sure that what the user entered is in fact an email is to actually send an email and see what happens. Other than that it’s all just guesses.
1
HTML5 itself has email validation. If your browser supports HTML5 then you can use the following code.
<form>
<label>Email Address
<input type="email" placeholder="me@example.com" required>
</label>
<input type="submit">
</form>
jsFiddle link
From the HTML5 spec:
A valid e-mail address is a string that matches the
email = 1*( atext / "." ) "@" label *( "." label ) label = let-dig [ [ ldh-str ] let-dig ] ; limited to a length of 63 characters by RFC 1034 section 3.5 atext = < as defined in RFC 5322 section 3.2.3 > let-dig = < as defined in RFC 1034 section 3.5 > ldh-str = < as defined in RFC 1034 section 3.5 >
This requirement is a willful violation of RFC 5322, which defines a syntax for e-mail addresses that is simultaneously too strict (before the «@» character), too vague (after the «@» character), and too lax (allowing comments, whitespace characters, and quoted strings in manners unfamiliar to most users) to be of practical use here.
The following JavaScript- and Perl-compatible regular expression is an implementation of the above definition.
/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
4
I have found this to be the best solution:
/^[^s@]+@[^s@]+.[^s@]+$/
It allows the following formats:
1. prettyandsimple@example.com 2. very.common@example.com 3. disposable.style.email.with+symbol@example.com 4. other.email-with-dash@example.com 9. #!$%&'*+-/=?^_`{}|~@example.org 6. "()[]:,;@\"!#$%&'*+-/=?^_`{}| ~.a"@example.org 7. " "@example.org (space between the quotes) 8. üñîçøðé@example.com (Unicode characters in local part) 9. üñîçøðé@üñîçøðé.com (Unicode characters in domain part) 10. Pelé@example.com (Latin) 11. δοκιμή@παράδειγμα.δοκιμή (Greek) 12. 我買@屋企.香港 (Chinese) 13. 甲斐@黒川.日本 (Japanese) 14. чебурашка@ящик-с-апельсинами.рф (Cyrillic)
It’s clearly versatile and allows the all-important international characters, while still enforcing the basic anything@anything.anything format. It will block spaces which are technically allowed by RFC, but they are so rare that I’m happy to do this.
0
In modern browsers you can build on top of @Sushil’s answer with pure JavaScript and the DOM:
function validateEmail(value) {
var input = document.createElement('input');
input.type = 'email';
input.required = true;
input.value = value;
return typeof input.checkValidity === 'function' ? input.checkValidity() : /S+@S+.S+/.test(value);
}
I’ve put together an example in the fiddle http://jsfiddle.net/boldewyn/2b6d5/. Combined with feature detection and the bare-bones validation from Squirtle’s Answer, it frees you from the regular expression massacre and does not bork on old browsers.
13
JavaScript can match a regular expression:
emailAddress.match( / some_regex /);
Here’s an RFC22 regular expression for emails:
^((?>[a-zA-Zd!#$%&'*+-/=?^_`{|}~]+x20*|"((?=[x01-x7f])[^"\]|\[x01-x7f])*
"x20*)*(?<angle><))?((?!.)(?>.?[a-zA-Zd!#$%&'*+-/=?^_`{|}~]+)+|"((?=[x01-x
7f])[^"\]|\[x01-x7f])*")@(((?!-)[a-zA-Zd-]+(?<!-).)+[a-zA-Z]{2,}|[(((?(?<
![).)(25[0-5]|2[0-4]d|[01]?d?d)){4}|[a-zA-Zd-]*[a-zA-Zd]:((?=[x01-x7f])
[^\[]]|\[x01-x7f])+)])(?(angle)>)$
2
All email addresses contain an ‘at’ (i.e. @) symbol. Test that necessary condition:
email.includes('@')
Or, if you need to support IE/older browsers:
email.indexOf('@') > 0
Don’t bother with anything more complicated. Even if you could perfectly determine whether an email is RFC-syntactically valid, that wouldn’t tell you whether it belongs to the person who supplied it. That’s what really matters.
To test that, send a validation message.
5
Correct validation of email address in compliance with the RFCs is not something that can be achieved with a one-liner regular expression. An article with the best solution I’ve found in PHP is What is a valid email address?. Obviously, it has been ported to Java. I think the function is too complex to be ported and used in JavaScript. JavaScript/node.js port: https://www.npmjs.com/package/email-addresses.
A good practice is to validate your data on the client, but double-check the validation on the server. With this in mind, you can simply check whether a string looks like a valid email address on the client and perform the strict check on the server.
Here’s the JavaScript function I use to check if a string looks like a valid mail address:
function looksLikeMail(str) {
var lastAtPos = str.lastIndexOf('@');
var lastDotPos = str.lastIndexOf('.');
return (lastAtPos < lastDotPos && lastAtPos > 0 && str.indexOf('@@') == -1 && lastDotPos > 2 && (str.length - lastDotPos) > 2);
}
Explanation:
-
lastAtPos < lastDotPos
: Last@
should be before last.
since@
cannot be part of server name (as far as I know). -
lastAtPos > 0
: There should be something (the email username) before the last@
. -
str.indexOf('@@') == -1
: There should be no@@
in the address. Even if@
appears as the last character in email username, it has to be quoted so"
would be between that@
and the last@
in the address. -
lastDotPos > 2
: There should be at least three characters before the last dot, for examplea@b.com
. -
(str.length - lastDotPos) > 2
: There should be enough characters after the last dot to form a two-character domain. I’m not sure if the brackets are necessary.
0
This is the correct RFC822 version.
function checkEmail(emailAddress) {
var sQtext = '[^\x0d\x22\x5c\x80-\xff]';
var sDtext = '[^\x0d\x5b-\x5d\x80-\xff]';
var sAtom = '[^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+';
var sQuotedPair = '\x5c[\x00-\x7f]';
var sDomainLiteral = '\x5b(' + sDtext + '|' + sQuotedPair + ')*\x5d';
var sQuotedString = '\x22(' + sQtext + '|' + sQuotedPair + ')*\x22';
var sDomain_ref = sAtom;
var sSubDomain = '(' + sDomain_ref + '|' + sDomainLiteral + ')';
var sWord = '(' + sAtom + '|' + sQuotedString + ')';
var sDomain = sSubDomain + '(\x2e' + sSubDomain + ')*';
var sLocalPart = sWord + '(\x2e' + sWord + ')*';
var sAddrSpec = sLocalPart + '\x40' + sDomain; // complete RFC822 email address spec
var sValidEmail = '^' + sAddrSpec + '$'; // as whole string
var reValidEmail = new RegExp(sValidEmail);
return reValidEmail.test(emailAddress);
}
6
This was stolen from http://codesnippets.joyent.com/posts/show/1917
email = $('email');
filter = /^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$/;
if (filter.test(email.value)) {
// Yay! valid
return true;
}
else
{return false;}
0
Do this:
^([a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?)$
It’s based on RFC 2822
Test it at https://regex101.com/r/857lzc/1
Often when storing email addresses in the database I make them lowercase and, in practice, regexs can usually be marked case insensitive. In those cases this is slightly shorter:
[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?
Here’s an example of it being used in JavaScript (with the case insensitive flag i
at the end).
var emailCheck=/^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i;
console.log( emailCheck.test('some.body@domain.co.uk') );
Note:
Technically some emails can include quotes in the section before the @
symbol with escape characters inside the quotes (so your email user can be obnoxious and contain stuff like @
and "..."
as long as it’s written in quotes). NOBODY DOES THIS EVER! It’s obsolete. But, it IS included in the true RFC 2822 standard and omitted here.
Note 2:
The beginning of an email (before the @ sign) can be case sensitive (via the spec). However, anyone with a case-sensitive email is probably used to having issues, and, in practice, case insensitive is a safe assumption. More info: Are email addresses case sensitive?
More info: http://www.regular-expressions.info/email.html
2
I’m really looking forward to solve this problem.
So I modified email validation regular expression above
-
Original
/^(([^<>()[]\.,;:s@"]+(.[^<>()[]\.,;:s@"]+)*)|(".+"))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9]+.)+[a-zA-Z]{2,}))$/
-
Modified
/^(([^<>()[].,;:s@"]+(.[^<>()[].,;:s@"]+)*)|(".+"))@(([^<>().,;s@"]+.{0,1})+[^<>().,;:s@"]{2,})$/
to pass the examples in Wikipedia Email Address.
And you can see the result in here.
0
Simply check out if the entered email address is valid or not using HTML.
<input type="email"/>
There isn’t any need to write a function for validation.
1
Wikipedia standard mail syntax :
https://en.wikipedia.org/wiki/Email_address#Examples
https://fr.wikipedia.org/wiki/Adresse_%C3%A9lectronique#Syntaxe_exacte
Function :
function validMail(mail)
{
return /^(([^<>()[].,;:s@"]+(.[^<>()[].,;:s@"]+)*)|(".+"))@(([^<>().,;s@"]+.{0,1})+([^<>().,;:s@"]{2,}|[d.]+))$/.test(mail);
}
Valid emails :
validMail('Abc@example.com') // Return true
validMail('Abc@example.com.') // Return true
validMail('Abc@10.42.0.1') // Return true
validMail('user@localserver') // Return true
validMail('Abc.123@example.com') // Return true
validMail('user+mailbox/department=shipping@example.com') // Return true
validMail('"very.(),:;<>[]".VERY."very@\ "very".unusual"@strange.example.com') // Return true
validMail('!#$%&'*+-/=?^_`.{|}~@example.com') // Return true
validMail('"()<>[]:,;@\"!#$%&'-/=?^_`{}| ~.a"@example.org') // Return true
validMail('"Abc@def"@example.com') // Return true
validMail('"Fred Bloggs"@example.com') // Return true
validMail('"Joe.\Blow"@example.com') // Return true
validMail('Loïc.Accentué@voilà.fr') // Return true
validMail('" "@example.org') // Return true
validMail('user@[IPv6:2001:DB8::1]') // Return true
Invalid emails :
validMail('Abc.example.com') // Return false
validMail('A@b@c@example.com') // Return false
validMail('a"b(c)d,e:f;g<h>i[jk]l@example.com') // Return false
validMail('just"not"right@example.com') // Return false
validMail('this is"notallowed@example.com') // Return false
validMail('this still"not\allowed@example.com') // Return false
validMail('john..doe@example.com') // Return false
validMail('john.doe@example..com') // Return false
Show this test : https://regex101.com/r/LHJ9gU/1
2
You should not use regular expressions to validate an input string to check if it’s an email. It’s too complicated and would not cover all the cases.
Now since you can only cover 90% of the cases, write something like:
function isPossiblyValidEmail(txt) {
return txt.length > 5 && txt.indexOf('@')>0;
}
You can refine it. For instance, ‘aaa@’ is valid. But overall you get the gist. And don’t get carried away… A simple 90% solution is better than 100% solution that does not work.
The world needs simpler code…
1
Regex updated! try this
let val = 'email@domain.com';
if(/^[a-z0-9][a-z0-9-_.]+@([a-z]|[a-z0-9]?[a-z0-9-]+[a-z0-9]).[a-z0-9]{2,10}(?:.[a-z]{2,10})?$/.test(val)) {
console.log('passed');
}
typscript version complete
//
export const emailValid = (val:string):boolean => /^[a-z0-9][a-z0-9-_.]+@([a-z]|[a-z0-9]?[a-z0-9-]+[a-z0-9]).[a-z0-9]{2,10}(?:.[a-z]{2,10})?$/.test(val);
more info https://git.io/vhEfc
2
It’s hard to get an email validator 100% correct. The only real way to get it correct would be to send a test email to the account. That said, there are a few basic checks that can help make sure that you’re getting something reasonable.
Some things to improve:
Instead of new RegExp
, just try writing the regexp
out like this:
if (reg.test(/@/))
Second, check to make sure that a period comes after the @
sign, and make sure that there are characters between the @
s and periods.
This is how node-validator does it:
/^(?:[w!#$%&'*+-/=?^`{|}~]+.)*[w!#$%&'*+-/=?^`{|}~]+@(?:(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-](?!.)){0,61}[a-zA-Z0-9]?.)+[a-zA-Z0-9](?:[a-zA-Z0-9-](?!$)){0,61}[a-zA-Z0-9]?)|(?:[(?:(?:[01]?d{1,2}|2[0-4]d|25[0-5]).){3}(?:[01]?d{1,2}|2[0-4]d|25[0-5])]))$/
A solution that does not check the existence of the TLD is incomplete.
Almost all answers to this questions suggest using Regex to validate emails addresses. I think Regex is only good for a rudimentary validation. It seems that the checking validation of email addresses is actually two separate problems:
1- Validation of email format: Making sure if the email complies with the format and pattern of emails in RFC 5322 and if the TLD actually exists. A list of all valid TLDs can be found here.
For example, although the address example@example.ccc
will pass the regex, it is not a valid email, because ccc
is not a top-level domain by IANA.
2- Making sure the email actually exists: For doing this, the only option is to send the users an email.
Use this code inside your validator function:
var emailID = document.forms["formName"]["form element id"].value;
atpos = emailID.indexOf("@");
dotpos = emailID.lastIndexOf(".");
if (atpos < 1 || ( dotpos - atpos < 2 ))
{
alert("Please enter correct email ID")
return false;
}
Else you can use jQuery. Inside rules define:
eMailId: {
required: true,
email: true
}
0
In contrast to squirtle, here is a complex solution, but it does a mighty fine job of validating emails properly:
function isEmail(email) {
return /^((([a-z]|d|[!#$%&'*+-/=?^_`{|}~]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])+(.([a-z]|d|[!#$%&'*+-/=?^_`{|}~]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])+)*)|((x22)((((x20|x09)*(x0dx0a))?(x20|x09)+)?(([x01-x08x0bx0cx0e-x1fx7f]|x21|[x23-x5b]|[x5d-x7e]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])|(\([x01-x09x0bx0cx0d-x7f]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF]))))*(((x20|x09)*(x0dx0a))?(x20|x09)+)?(x22)))@((([a-z]|d|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])|(([a-z]|d|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])([a-z]|d|-|.|_|~|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])*([a-z]|d|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF]))).)+(([a-z]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])|(([a-z]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])([a-z]|d|-|.|_|~|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])*([a-z]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])))$/i.test(email);
}
if (isEmail('youremail@yourdomain.com')){ console.log('This is email is valid'); }
0
var testresults
function checkemail() {
var str = document.validation.emailcheck.value
var filter = /^([w-]+(?:.[w-]+)*)@((?:[w-]+.)*w[w-]{0,66}).([a-z]{2,6}(?:.[a-z]{2})?)$/i
if (filter.test(str))
testresults = true
else {
alert("Please input a valid email address!")
testresults = false
}
return (testresults)
}
function checkbae() {
if (document.layers || document.getElementById || document.all)
return checkemail()
else
return true
}
<form name="validation" onSubmit="return checkbae()">
Please input a valid email address:<br />
<input type="text" size=18 name="emailcheck">
<input type="submit" value="Submit">
</form>
0
My knowledge of regular expressions is not that good. That’s why I check the general syntax with a simple regular expression first and check more specific options with other functions afterwards. This may not be not the best technical solution, but this way I’m way more flexible and faster.
The most common errors I’ve come across are spaces (especially at the beginning and end) and occasionally a double dot.
function check_email(val){
if(!val.match(/S+@S+.S+/)){ // Jaymon's / Squirtle's solution
// Do something
return false;
}
if( val.indexOf(' ')!=-1 || val.indexOf('..')!=-1){
// Do something
return false;
}
return true;
}
check_email('check@thiscom'); // Returns false
check_email('check@this..com'); // Returns false
check_email(' check@this.com'); // Returns false
check_email('check@this.com'); // Returns true
Regex for validating email address
[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])+
0
Here is a very good discussion about using regular expressions to validate email addresses; «Comparing E-mail Address Validating Regular Expressions»
Here is the current top expression, that is JavaScript compatible, for reference purposes:
/^[-a-z0-9~!$%^&*_=+}{'?]+(.[-a-z0-9~!$%^&*_=+}{'?]+)*@([a-z0-9_][-a-z0-9_]*(.[-a-z0-9_]+)*.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|mobi|[a-z][a-z])|([0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}))(:[0-9]{1,5})?$/i
1
Apparently, that’s it:
/^([w!#$%&'*+-/=?^`{|}~]+.)*[w!#$%&'*+-/=?^`{|}~]+@((((([a-z0-9]{1}[a-z0-9-]{0,62}[a-z0-9]{1})|[a-z]).)+[a-z]{2,6})|(d{1,3}.){3}d{1,3}(:d{1,5})?)$/i
Taken from http://fightingforalostcause.net/misc/2006/compare-email-regex.php on Oct 1 ’10.
But, of course, that’s ignoring internationalization.
0
Wow, there are a lot of answers that contain slightly different regular expressions. I’ve tried many that I’ve got different results and a variety of different issues with all of them.
For UI validation, I’m good with the most basic check of looking for an @ sign. It’s important to note, that I always do server-side validation with a standard «validate email» that contains a unique link for the user to confirm their email address.
if (email.indexOf('@') > 0)
I have purposely chosen 0 even with zero-based as it also ensures there is a single character before the @.
In this article, you will discover three ways to do an email validation with JavaScript (using Regular Expressions, an Email Validator library, or HTML5).
An old myth says that you are a web development wizard once you create a contact form! 🧙😄
Unknown
Email validation using Regular Expressions
The most common way to validate an email with JavaScript is to use a regular expression (RegEx). Regular expressions will help you to define rules to validate a string.
If we summarize, an email is a string following this format:
First part of an email
- uppercase and lowercase letters: a-z and A-Z
- digits: 0-9
- hyphens: – (not the last or first character)
- dots: . (not the last or first character)
Note: Some email providers allows email adresses with these character: `! # $ % & ‘ * + / = ? ^ _ { | } ~ " ( ) , : ; < > @ [ ]`. It will depends if you want to accept these mails, but most website rejects them.
Second part of an email
- uppercase and lowercase letters: a-z and A-Z
- digits: 0-9
- hyphens: – (not the last or first character)
Third part of an email
- uppercase and lowercase letters: a-z and A-Z
- digits: 0-9
- dots: . (not the last or first character)
Here is an email regex expression:
/^[a-zA-Z0-9][-_.+!#$%&'*/=?^`{|]{0,1}([a-zA-Z0-9][-_.+!#$%&'*/=?^`{|]{0,1})*[a-zA-Z0-9]@[a-zA-Z0-9][-.]{0,1}([a-zA-Z][-.]{0,1})*[a-zA-Z0-9].[a-zA-Z0-9]{1,}([.-]{0,1}[a-zA-Z]){0,}[a-zA-Z0-9]{0,}$/i
In JavaScript, you can use this function for your email validation.
function isEmailValid(email) {
const emailRegexp = new RegExp(
/^[a-zA-Z0-9][-_.+!#$%&'*/=?^`{|]{0,1}([a-zA-Z0-9][-_.+!#$%&'*/=?^`{|]{0,1})*[a-zA-Z0-9]@[a-zA-Z0-9][-.]{0,1}([a-zA-Z][-.]{0,1})*[a-zA-Z0-9].[a-zA-Z0-9]{1,}([.-]{0,1}[a-zA-Z]){0,}[a-zA-Z0-9]{0,}$/i
)
return emailRegexp.test(email)
}
console.log(isEmailValid('helloitsme@herewecode.io')) // true
console.log(isEmailValid('hello-its-me@herewecode.io')) // true
console.log(isEmailValid('hello.its.me@herewecode.io')) // true
console.log(isEmailValid('helloitsme+test@herewecode.io')) // true
console.log(isEmailValid('.helloitsme@herewecode.io')) // false
console.log(isEmailValid('helloitsme.@herewecode.io')) // false
console.log(isEmailValid('@herewecode.io')) // false
console.log(isEmailValid('helloitsmeherewecode.io')) // false
console.log(isEmailValid('helloitsme@herewecode')) // false
console.log(isEmailValid('d@d.o')) // false
Note: As you can imagine, this Regex isn't homemade. I found it on Stack Overflow; then, I updated it to match the email string format explained above.
Email validation using an Email Validator
If you don’t want to create a custom function to validate emails, you can use libraries.
When we type: “email validation library javascript” on Google, the first result is the “email validator” library.
Here is an example of how to use it:
const validator = require('email-validator')
console.log(validator.validate('helloitsme@herewecode.io')) // true
console.log(validator.validate('hello-its-me@herewecode.io')) // true
console.log(validator.validate('hello.its.me@herewecode.io')) // true
console.log(validator.validate('helloitsme+test@herewecode.io')) // true
console.log(validator.validate('.helloitsme@herewecode.io')) // false
console.log(validator.validate('helloitsme.@herewecode.io')) // false
console.log(validator.validate('@herewecode.io')) // false
console.log(validator.validate('helloitsmeherewecode.io')) // false
console.log(validator.validate('helloitsme@herewecode')) // false
console.log(validator.validate('d@d.o')) // false
Email validator is one library among others. You can find a lot of them with different features online.
Email validation using HTML5 input validation
The last way to validate an email is to use an HTML5 email input.
<input type="email" id="email" name="email" placeholder="email" />
Here is an example of an email validation using a simple form:
<!DOCTYPE html>
<html>
<body>
<h1>JavaScript Validate Email</h1>
<p>Write your email and we will validate it:</p>
<form>
<input type="email" id="email" name="email" placeholder="Email" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
As you can see, HTML triggers an error when the email address isn’t correct. However, if we type, for example: “helloitsme@herewecode” or “-herewecode.io”, the form is valid.
This option is a good feature that you should use when you implement a form on your website. It’s suitable for a first validation, but don’t forget to validate yourself to avoid issues.
Bonus: Email validation using an API
As a bonus, you can validate emails using APIs. Here are some companies proposing email validation APIs: SendGrid, MailBoxLayer, Abstract API, etc.
Most of these APIs are not free, but they will provide you some advanced features (ex: check if an email exists).
Thanks for reading. Let’s connect!
➡️ I help you grow into Web Development, and I share my journey as a Nomad Software Engineer. Join me on Twitter for more. 🚀🎒
Простая валидация email с помощью javaScript. Суть в том, чтобы не дать отправить форму, пока не будет правильно введен email.
Форма обязательно должна валидироваться еще и на сервере, иначе, отключив javaScript можно отправить любое содержимое вместо email.
Простой пример HTML (поле для ввода, кнопка и сообщение для вывода ошибки):
<form class="form" action="javascript:void(0)"> <div class="form-row"> <div class="form-col"> <input type="text" class="email" placeholder="E-mail"> <span class="error"></span> </div> </div> <button type="submit" class="btn-submit">Get Discount</button> </form>
Функционал данной задачи поместился в 3 небольших функции. Код javaScript:
$(function() { $(".btn-submit").on("click", validate); // Validate email function validateEmail(email) { var re = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/; return re.test(String(email).toLowerCase()); } // send form function sendForm() { $(".error").text("Form sending").fadeIn(); } // validate email and send form after success validation function validate() { var email = $(".email").val(); var $error = $(".error"); $error.text(""); if (validateEmail(email)) { $error.fadeOut(); sendForm(); } else { $error.fadeIn(); $error.text(email + " is not valid"); } return false; } });
Рассмотрим чуть подробнее скрипт.
function validateEmail(email)
— функция, которая проверяет соответствие строки email
регулярному выражению, указанному в переменной re
. В переменной re
задана регулярка для шаблона email-почты.
function sendForm()
— простой пример, чтобы показать, что форма отправлена, в рабочем примере здесь будет сообщение об успешной отправке и отправка формы.
function validate()
— функция которая будет вызвана после нажатия на кнопку ".btn-submit"
. Будет провалидирован введенный в поле email, если он не соответствует регулярному выражению, то появится сообщение об ошибке, а если почта валидна, то форма будет отправлена и мы получим уведомление об успешной отправке почты.
Пример работы валидации email:
See the Pen simple validation email by javascript by Denis (@deniscreative) on CodePen.default
Больше примеров regular expresion для email можно найти здесь.
2 способа прижать футер к нижней части страницы (подходит для IE10 & Edge)
Рассмотрим 2 наиболее часто применяющихся примера. Для обоих примеров будет общий HTML: И общие правила…
Убрать стрелки в input[type=»number»] с помощью CSS
Простой пример, как убрать стрелки в поле input[type=»number»] с помощью CSS: Важное дополнение: по прежнему…
Событие ‘click’ не срабатывает на iPhone и некоторых мобильных браузерах — решение проблемы
Часто в мобильной версии сайта используется кнопка типа «бургера» для вызова основного меню сайта. На…
fadeIn() для flex-контейнера
Суть задачи в том, чтобы сделать плавное появление и скрытие flex-контейнера. Если использовать просто fadeIn(),…
Время на прочтение
3 мин
Количество просмотров 146K
В этой статье рассмотривается валидация email изпользуя регулярные выражения. Все регэкспы выполняются с модификатором i
, т.е. делают регистронезависимую проверку.
Подготовка
Перед тем как писать валидацию, надо знать из чего состоит email адрес. Думаю известно всем что это «username@hostname». Лучше всего будет разбить создание регэкспа на 2 логические части — валидация hostname и валидация username. Начнём с более объёмного.
Валидация hostname
Для начала подумаем, а из чего же состоит hostname?
Имя хоста состоит из нескольких компонентов, разделённых точкой и не превышающих 63 символа, и суффиксов (домены первого уровня). Компоненты, в свою очередь, состоят из латинских букв, цифр и дефисов, причём дефисы не могут быть в начале или в конце компонента. Суффиксы это ограниченный список доменов первого уровня (я нашёл список на сайте IANA). Для упрощения выражения запишем домены стран как [a-z][a-z]
(любые 2 символа от a до z не зависимо от регистра). Так же не будем использовать не латинские символы, пока они официально не введены в публичное пользование. В итоге получим выражение проверяющее суффикс (конструкция (foo|bar)
говорит о том что происходит поиск либо foo либо bar, т.е. заменяет или):
(aero|arpa|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|[a-z][a-z])
Для компонентов код будет посложнее:
([a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?.)
Разберём выражение:
[a-z0-9] # обязательная буква латинского алфавита или цифра
([-a-z0-9]{0,61}[a-z0-9])? # необязательная часть
. # точка
Рассмотрим необязательную часть:
# дефис ставиться на первое место в группе символов, иначе он принимается за промежуток
# {0,61} после группы символов означает, что группа может повторятся от 0 до 61 раза
[-a-z0-9]{0,61}
# 61 для того, чтобы в группе не было более 63 символов в сумме
[a-z0-9]
В итоге мы получили выражение отвечающее за проверку hostname:
([a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?.)*(aero|arpa|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|[a-z][a-z])
Обращу внимание на то, что присутствие компонентов не обязательно, т.к. некоторые домены первого уровня поддерживаются серверами. Пример.
Валидация username
Имя пользователя может в себе содержать:
- латиницу
- цифры
- знаки! # $ % & ‘ * + — / =? ^ _ ` { | } ~
- точку, за исключением первого и последнего знака, которая не может повторятся
Приведу сразу выражение:
[-a-z0-9!#$%&'*+/=?^_`{|}~]+(.[-a-z0-9!#$%&'*+/=?^_`{|}~]+)*
На самом деле тут все просто: 1 или более символ [-a-z0-9!#$%&'*+/=?^_`{|}~]
, далее 0 или больше компонентов .[-a-z0-9!#$%&'*+/=?^_`{|}~]+
.
В итоге
Регэксп проверки email:
^[-a-z0-9!#$%&'*+/=?^_`{|}~]+(.[-a-z0-9!#$%&'*+/=?^_`{|}~]+)*@([a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?.)*(aero|arpa|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|[a-z][a-z])$
Это выражение можно каплю оптимизировать (про оптимизацию, я думаю, будет отдельная статья):
^[-a-z0-9!#$%&'*+/=?^_`{|}~]+(?:.[-a-z0-9!#$%&'*+/=?^_`{|}~]+)*@(?:[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?.)*(?:aero|arpa|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|[a-z][a-z])$
Бонус
Рассмотрим регэксп, который привели в пример в комментарии к вступительному топику:
^(S+)@([a-z0-9-]+)(.)([a-z]{2,4})(.?)([a-z]{0,4})+$
Какие тут есть главные проблемы?
- Так как username может состоять из любых символов кроме пробелов, username «日本国» является валидным.
- Домен первого уровня может состоять из любых 4 латинских букв, например .habr
- Ужасная проверка домена: 1 или более символов, обязательная точка, 2-4 обязательных символа, необязательная точка, 0-4 символа в прибавок. Причём каждый из этих блоков сохраняется в память.
P.S. Пишите о багах и пожеланиях — обязательно исправлю.
P.P.S. По желанию могу выложить функцию проверки email, используюмую мной.