[html] HTML5 Email input pattern attribute

I’m trying to make a html5 form that contains one email input, one check box input, and one submit input. I'm trying to use the pattern attribute for the email input but I don't know what to place in this attribute. I do know that I'm supposed to use a regular expression that must match the JavaScript Pattern production but I don't know how to do this.

What I'm trying to get this attribute to do is to check to make sure that the email contains one @ and at least one or more dot and if possible check to see if the address after the @ is a real address. If I can't do this through this attribute then I'll consider using JavaScript but for checking for one @ and one or more dot I do want to use the pattern attribute for sure.

The pattern attribute needs to check for:

  1. Only one @
  2. One or more dot
  3. And if possible check to see if the address after the @ is a valid address

An alternative to this one is to use a JavaScript but for all the other conditions I do not want to use a JavaScript.

This question is related to html html-email email-validation html-input

The answer is


<input type="email" pattern="^[^ ]+@[^ ]+\.[a-z]{2,6}$">

Demo - Test the email input


Updated 2018 Answer

Go here http://emailregex.com/

Javascript:

/^(([^<>()\[\]\\.,;:\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,}))$/


One more solution that is built on top of w3org specification.
Original regex is taken from w3org.
The last "* Lazy quantifier" in this regex was replaced with "+ One or more quantifier".
Such a pattern fully complies with the specification, with one exception: it does not allow top level domain addresses such as "foo@com"

<input
    type="email" 
    pattern="[a-zA-Z0-9.!#$%&amp;’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)+"
    title="[email protected]"
    placeholder="[email protected]"
    required>

^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$

In HTML5 you can use the new 'email' type: http://www.w3.org/TR/html-markup/input.email.html

For example:

<input type="email" id="email" />

If the browser implements HTML5 it will make sure that the user has entered a valid email address in the field. Note that if the browser doesn't implement HTML5, it will be treated like a 'text' type, ie:

<input type="text" id="email" />

<input type="email" name="email" id="email" value="" placeholder="Email" required />

documentation http://www.w3.org/TR/html-markup/input.email.html


This is the approach I'm using and you can modify it based on your needs:

^[\w]{1,}[\w.+-]{0,}@[\w-]{2,}([.][a-zA-Z]{2,}|[.][\w-]{2,}[.][a-zA-Z]{2,})$

Explanation:

  1. We want to make sure that the e-mail address always starts with a word:

    ^[\w]

A word is any character, digit or underscore. You can use [a-zA-Z0-9_] pattern, but it will give you the same result and it's longer.

  1. Next, we want to make sure that there is at least one such character:

    ^[\w]{1,}

  2. Next, we want to allow any word, digit or special characters in the name. This way, we can be sure that the e-mail won't start with the dot, but can contain the dot on other than the first position:

    ^[\w]{1,}[\w.+-]

  3. And of course, there doesn't have to be any of such character because e-mail address can have only one letter followed by @:

    ^[\w]{1,}[\w.+-]{0,}

  4. Next, we need the @ character which is mandatory, but there can be only one in the whole e-mail:

    ^[\w]{1,}[\w.+-]{0,}@

  5. Right behind the @ character, we want the domain name. Here, you can define how many characters you want as minimum and from which range of characters. I'd go for all word characters including the hyphen [\w-] and I want at least two of them {2,}. If you want to allow domains like t.co, you would have to allow one character from this range {1,}:

    ^[\w]{1,}[\w.+-]{0,}@[\w-]{2,}

  6. Next, we need to deal with two cases. Either there's just the domain name followed by the domain extension, or there's subdomain name followed by the domain name followed by the extension, for example, abc.com versus abc.co.uk. To make this work, we need to use the (a|b) token where a stands for the first case, b stands for the second case and | stands for logical OR. In the first case, we will deal with just the domain extension, but since it will be always there no matter the case, we can safely add it to both cases:

    ^[\w]{1,}[\w.+-]{0,}@[\w-]{2,}([.][a-zA-Z]{2,}|[.][a-zA-Z]{2,})

This pattern says that we need exactly one dot character followed by letters, no digits, and we want at least two of them, in both cases.

  1. For the second case, we will add the domain name in front of the domain extension, thus making the original domain name a subdomain:

    ^[\w]{1,}[\w.+-]{0,}@[\w-]{2,}([.][a-zA-Z]{2,}|[.][\w-]{2,}[.][a-zA-Z]{2,})

The domain name can consist of word characters including the hyphen and again, we want at least two characters here.

  1. Finally, we need to mark the end of the whole pattern:

    ^[\w]{1,}[\w.+-]{0,}@[\w-]{2,}([.][a-zA-Z]{2,}|[.][\w-]{2,}[.][a-zA-Z]{2,})$

  2. Go here and test if your e-mail matches the pattern: https://regex101.com/r/374XLJ/1


Unfortunately, all suggestions except from B-Money are invalid for most cases.

Here is a lot of valid emails like:

Because of complexity to get validation right, I propose a very generic solution:

<input type="text" pattern="[^@\s]+@[^@\s]+\.[^@\s]+" title="Invalid email address" />

It checks if email contains at least one character (also number or whatever except another "@" or whitespace) before "@", at least two characters (or whatever except another "@" or whitespace) after "@" and one dot in between. This pattern does not accept addresses like lol@company, sometimes used in internal networks. But this one could be used, if required:

<input type="text" pattern="[^@\s]+@[^@\s]+" title="Invalid email address" />

Both patterns accepts also less valid emails, for example emails with vertical tab. But for me it's good enough. Stronger checks like trying to connect to mail-server or ping domain should happen anyway on the server side.

BTW, I just wrote angular directive (not well tested yet) for email validation with novalidate and without based on pattern above to support DRY-principle:

.directive('isEmail', ['$compile', '$q', 't', function($compile, $q, t) {
    var EMAIL_PATTERN = '^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$';
    var EMAIL_REGEXP = new RegExp(EMAIL_PATTERN, 'i');
    return {
        require: 'ngModel',
        link: function(scope, elem, attrs, ngModel){
            function validate(value) {
                var valid = angular.isUndefined(value)
                    || value.length === 0
                    || EMAIL_REGEXP.test(value);
                ngModel.$setValidity('email', valid);
                return valid ? value : undefined;
            }
            ngModel.$formatters.unshift(validate);
            ngModel.$parsers.unshift(validate);
            elem.attr('pattern', EMAIL_PATTERN);
            elem.attr('title', 'Invalid email address');
        }
    };
}])

Usage:

<input type="text" is-email />

For B-Money's pattern is "@" just enough. But it decline two or more "@" and all spaces.


A simple good answer can be an input like this:

_x000D_
_x000D_
input:not(:placeholder-shown):invalid{
  background-color:pink;
  box-shadow:0 0 0 2px red;
}
/* :not(:placeholder-shown) = when it is empty, do not take as invalid */
/* :not(:-ms-placeholder-shown) use for IE11 */
/* :invalid = it is not followed pattern or maxlength and also if required and not filled */
/* Note: When autocomplete is on, it is possible the browser force CSS to change the input background and font color, so i used box-shadow for second option*/
_x000D_
Type your Email:
<input 
  type="email"
  name="email"
  lang="en"
  maxlength="254"
  value=""
  placeholder="[email protected]"
  autocapitalize="off" spellcheck="false" autocorrect="off"
  autocomplete="on"
  required=""
  inputmode="email"
  pattern="^(?![\.\-_])((?![\-\._][\-\._])[a-z0-9\-\._]){0,63}[a-z0-9]@(?![\-])((?!--)[a-z0-9\-]){0,63}[a-z0-9]\.(|((?![\-])((?!--)[a-z0-9\-]){0,63}[a-z0-9]\.))(|([a-z]{2,14}\.))[a-z]{2,14}$">
_x000D_
_x000D_
_x000D_

According to the following:

https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inputmode https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/email

  • Maximum length of domain in URL (254 Character)
  • Longest possible Subdomain(Maybe =0-64 character), Domain (=0-64 character), First Level Extension(=2-14 character), Second Level Extension(Maybe =2-14 character) as @Brad motioned.
  • Avoiding of not usual but allowed characters in Email name and just accepting usual characters that famous free email services like Outlook, Yahoo, Gmail etc. will just accept them. It means accepting just : dot (.), dash (-), underscore (_) just in between a-z (lowercase) and numbers and also not accepting double of them next to each other and maximum 64 characters.

Note: Right now, longer address and even Unicode characters are possible in URL and also a user can send email to local or an IP, but i think still it is better to not accepting unusual things if the target page is public.

Explain of the regex:

  1. ^...$ from first till end
  2. (?![\.\-_]) not started with these: . - _
  3. ((?!--)[a-z0-9\-]) accept a till z and numbers and - but not --
  4. ((?![\-\._][\-\._])[a-z0-9\-\._]) from a till z lowercase and numbers and also . - _ accepted but not any kind of double of them.
  5. {0,63} Length from zero till 63 (the second group [a-z0-9] will fill the +1 but do not let the just character be . - _)
  6. @ The at sign
  7. (|(rule)) not exist or if exist should follow the rule. (For Subdomain and Second Level Extension)
  8. \. Dot

Explaining of attributes:

type="email" In modern browsers help also for valid email address

name="email" autocomplete="on" To browser remember easy last filled input for auto completing

lang="en" Helping for default input be English

inputmode="email" Will help to touch keyboards be more compatible

maxlength="254" Setting the maximum length of the input

autocapitalize="off" spellcheck="false" autocorrect="off" Turning off possible wrong auto correctors in browser

required="" This field is required to if it was empty or invalid, form be not submitted

pattern="..." The regex inside will check the validation


You probably want something like this. Notice the attributes:

  • required
  • type=email
  • autofocus
  • pattern

<input type="email" value="" name="EMAIL" id="EMAIL" placeholder="[email protected]" autofocus required pattern="[^ @]*@[^ @]*" />


I had this exact problem with HTML5s email input, using Alwin Keslers answer above I added the regex to the HTML5 email input so the user must have .something at the end.

<input type="email" pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$" />

The following regex pattern should work with most emails, including russian emails.

[^@]+@[^\.]+\..+


If you don,t want to write a whitepaper about Email-Standards, then use my following example which just introduce a well known CSS attribute(text-transform: lowercase) to solve the problem:

_x000D_
_x000D_
<input type="email" name="email" id="email" pattern="[a-zA-Z0-9._%+-]+@[a-z0-9.-]+\.[a-zA-Z]{2,4}" style="text-transform: lowercase" placeholder="enter email here ..." title="please enter a valid email" />
_x000D_
_x000D_
_x000D_


I used following Regex to satisfy for following emails.

[email protected] # Minimum three characters
[email protected] # Accepts Caps as well.
[email protected] # Accepts . before @

Code

<input type="email" pattern="[A-Za-z0-9._%+-]{3,}@[a-zA-Z]{3,}([.]{1}[a-zA-Z]{2,}|[.]{1}[a-zA-Z]{2,}[.]{1}[a-zA-Z]{2,})" />

pattern="[a-z0-9._%+-]{1,40}[@]{1}[a-z]{1,10}[.]{1}[a-z]{3}"

<input type="email"  class="form-control" id="driver_email" placeholder="Enter Driver Email" name="driver_email" pattern="[a-z0-9._%+-]{1,40}[@]{1}[a-z]{1,10}[.]{1}[a-z]{3}" required="">

<input name="email" type="email" pattern="[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{1,63}$" class="form-control" placeholder="Email*" id="email" required="">

This is modified version of above solution which accept capital letter as well.


I have tested the following regex which gives the same result as Chrome Html email input validation.

[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9-]+(\.[a-z0-9-]+)*

You can test it out on this website: regex101


Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to html-email

html tables & inline styles CSS to make table 100% of max-width Send a base64 image in HTML email How do I send email with JavaScript without opening the mail client? Color a table row with style="color:#fff" for displaying in an email Has anyone gotten HTML emails working with Twitter Bootstrap? Styling HTML email for Gmail How do I remove link underlining in my HTML email? Remove spacing between table cells and rows HTML5 Email input pattern attribute

Examples related to email-validation

Email address validation in C# MVC 4 application: with or without using Regex Email address validation using ASP.NET MVC data type attributes Best Regular Expression for Email Validation in C# Email Address Validation in Android on EditText How to validate an email address in PHP Can there be an apostrophe in an email address? How to check for valid email address? How to check edittext's text is email address or not? How to validate an Email in PHP? HTML5 Email input pattern attribute

Examples related to html-input

Using Pipes within ngModel on INPUT Elements in Angular HTML 5 input type="number" element for floating point numbers on Chrome Html/PHP - Form - Input as array How to locate and insert a value in a text box (input) using Python Selenium? Drop Down Menu/Text Field in one HTML5 pattern for formatting input box to take date mm/dd/yyyy? How to add button inside input How to handle floats and decimal separators with html5 input type number How to set default value to the input[type="date"] Get data from file input in JQuery