48

I'm making a really simple email validation script that basically just checks the following

  1. that the email isn't blank
  2. the the email contains an @ symbol with at least 1 character before it
  3. that there is a domain ie @ with at least 2 letters after it
  4. that it ends with a fullstop with at least 2 letters after it

I know there are many more checks, but I look at these regex rules and my mind stops working. I figure if I started with something small like this I might be able to wrap my brain around more complex rules.

Currently using some jQuery I do the following:

 var booking_email = $('input[name=booking_email]').val();

 if(booking_email == '' || booking_email.indexOf('@') == -1 || booking_email.indexOf('.') == -1) {

   // perform my alert

 }

This is enough to stop 90% of bogus emails so far... I would just like to make it a bit more effective because currently my rule will allow emails like '@example.com' or 'user@domain.' because it only checks that there is a fullstop and an @ symbol.

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
willdanceforfun
  • 11,044
  • 31
  • 82
  • 122
  • A tool that might help with RegEx is [this Analyzer](http://xenon.stanford.edu/~xusch/regexp/analyzer.html). – sdleihssirhc Feb 11 '11 at 01:36
  • 1
    u prefer a solution with regex or plain simple javascript ? – Shlomi Komemi Feb 11 '11 at 01:46
  • 1
    plain simple javascript.. regex is probably better but I don't like the unintuitive formatting of it. – willdanceforfun Feb 11 '11 at 04:26
  • 1
    I don't like using code I can't look at and easily understand ie copy and pasting regex stuff. Simply because if I get a complaint about an email not working, I can't look at it simply and get a good idea as to why the script isn't working. – willdanceforfun Feb 11 '11 at 04:27
  • About two years ago I wrote this: http://stackoverflow.com/questions/3232/how-far-should-one-take-e-mail-address-validation/300862#300862 – some Feb 11 '11 at 04:48
  • Regarding the 3rd check - there *are* single letter domains. https://en.wikipedia.org/wiki/Single-letter_second-level_domain – targumon Mar 10 '21 at 19:04
  • fun fact: domains [don't need a dot in the slightest](https://stackoverflow.com/a/20573804/740553), you can send emails to `someone@localhost` just fine. So with that said: just use `` in a form and make it do the validation for you, instead of rolling your own code? Browsers kind of have this built in already. – Mike 'Pomax' Kamermans Jul 21 '21 at 03:08

10 Answers10

87

What others have suggested should work fine, but if you want to keep things simple, try this:

var booking_email = $('input[name=booking_email]').val();

if( /(.+)@(.+){2,}\.(.+){2,}/.test(booking_email) ){
  // valid email
} else {
  // invalid email
}

Even if you decide to go with something more robust, it should help you understand how simple regex can be at times. :)

AlienWebguy
  • 76,997
  • 17
  • 122
  • 145
Ashley Williams
  • 6,770
  • 4
  • 35
  • 42
  • 6
    nice, you posted like 11 seconds before me. albeit this RegExp is kind of correct, there's no need to use capturing parens, you should use `test` instead of `search` and it's always a good practice to anchor your RegExps. – gonchuki Feb 11 '11 at 01:39
  • Not sure what you mean by "anchor[ing] your RegExps", but you're right, `text` is faster than `search`. :) – Ashley Williams Feb 11 '11 at 01:46
  • 6
    the `^` at the start and `$` at the end are 'anchors'. They dictate that the string must exactly begin with what comes next to the ^, and end with what comes before the $. A simple way to view this is that `/a/` will match against ' a', but `/^a/` will not. – gonchuki Feb 11 '11 at 02:25
  • Oh right, yes. Is it important in this example though, will the above match something it should not, where the anchored version wouldn't? Or would anchoring it only be important if the regex was a little bit more complex, i.e. not accepting spaces within the string? – Ashley Williams Feb 11 '11 at 18:34
  • 2
    Can it be changed to allow only one `@` sign in email id? – IsmailS Sep 19 '14 at 12:06
  • 1
    `/(.+)@(.+){2,}\.(.+){2,}/.test('d @ . df ')` Is also true... I think you can do better. – Rhys van der Waerden May 29 '15 at 01:14
  • 4
    I mean, this is clearly just wrong. It should either be fixed or at least not accepted as the answer. – Rhys van der Waerden May 29 '15 at 01:17
  • 1
    isn't this redundant? `(.+){2,}` it means "any character one or more times, at least two or more times" ... shouldn't it just be `.{2,}` – Francisc0 Apr 23 '18 at 19:32
  • @Francisc0 Or even shorter `..+`. – Mattias Wallin Mar 19 '21 at 07:25
  • Quite simple, but also ```"yeah! I love... @ - . @ . @x"``` would validate, I'd rather suggest: ```new RegExp("^([^\@ ]+)\@(([^\@ .]+){2,}\.)+([^\@ .]+){2,}$")``` – Marco Balestra Dec 19 '21 at 11:41
  • 1
    There is something very wrong with this regex, DO NOT USE. This is the second regex we try that causes issues. This one hangs the CPU on large emails as: somelargeruser@someevenlargerdomainname.com – pedroassis Dec 27 '22 at 19:19
61

The least possible greedy validation you an do is with this RegExp /^\S+@\S+\.\S+$/

It will only ensure that the address fits within the most basic requirements you mentioned: a character before the @ and something before and after the dot in the domain part (\S means "anything but a space"). Validating more than that will probably be wrong (you always have the chance of blacklisting a valid email).

Use it like this:

function maybeValidEmail (email) { return /^\S+@\S+\.\S+$/.test(email); }
rattray
  • 5,174
  • 1
  • 33
  • 27
gonchuki
  • 4,064
  • 22
  • 33
  • 2
    This is good for what I was looking for. I'll do more validation on the back end, but it's convenient to allow JS to at least weed out the more obvious fakes. – Ashley Strout Oct 27 '12 at 14:34
  • 6
    this is better than the accepted answer. What do you think about taking it one step further and using the "non whitespace" shortcut like this `\S+@\S+\.\S+` ? because right now the `.` will also accept whitespace characters which shouldn't be allowed in an email – Francisc0 Apr 23 '18 at 19:46
  • Ditto @Francisc0 right now, you can submit "hello @world.com" - but yeah, good regex – stephenmurdoch Sep 28 '18 at 13:35
  • 2
    You should restrict the @ sign instead of allowing any character like in geedew's answer. Otherwise this allows any number of @ signs. Even simply "@@@.@" will pass. – Phil Sep 04 '20 at 17:50
  • 1
    "Otherwise this allows any number of @ signs". It's still a valid email to have more than one @ sign. – Daniel Ryan Aug 17 '21 at 02:59
  • 1
    Nice that this solution also works for non-English emails. – Daniel Ryan Aug 17 '21 at 03:02
3

Try:

function valid_email(email) {
   return email.match(/^([\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);
}

That is the best available email validation regex, according to this article. I recommend using this, unless your goal is something really simple but not fully compatible.

Maxim Zaslavsky
  • 17,787
  • 30
  • 107
  • 173
  • This doesn't return a true/false match as it does all patterns that may match valid email patterns. It should return email.test(....); even so - it returns false on valid patterns containing special characters unless you specifically exclude them from the validation (such as ') via something like escape() [which also kills it] --- as posted in an earlier comment, all of the "maybe" characters make effective regex nearly impossible. Best to test with a simple routine followed by email validation: http://www.remote.org/jochen/mail/info/chars.html (this is based solely on RFC validation) – iivel Feb 11 '11 at 02:33
  • this is now wrong, the TLD portion [a-z]{2,6} is out of date, that needs to be [a-z]{2,18} (YES, 18 Letters) because of the TLDs like .NORTHWESTERNMUTUAL and .TRAVELERSINSURANCE –  Dec 09 '22 at 01:46
2

RegexLib.com ( http://regexlib.com/Search.aspx?k=email ) has hundreds of email validation routines for a reason. I'd recommend you read this article: http://www.unwrongest.com/blog/email-validation-regular-expressions/ and if you decide to continue using regex for validation, my favorite testing utility is the free regex designer available for free here: http://www.radsoftware.com.au/regexdesigner/ ... test all emails in a LARGE list (available for free download or purchase ... or use your own current DB) to ensure your regex is acceptable within your constraints.

I would recommend a basic test (many at the top of regexlib.com ... I'm not taking credit for the work of theirs I use routinely), followed by a email validation routine that requires user interaction. It is the only real way to 'validate' an email address.

iivel
  • 2,576
  • 22
  • 19
1

Emails are very difficult to test, but you can have a somewhat restrictive, but simple email validation. I use this one myself, which does a pretty decent job of making sure it's 95% an email address.

var simpleValidEmail = function( email ) {
    return email.length < 256 && /^[^@]+@[^@]{2,}\.[^@]{2,}$/.test(email);
};

I would recommend this for a 'simple' validation.

To see why this is a hard thing to solve, see: How to validate an email address using a regular expression?

Update: corrected regular expression

JimmyBlu
  • 648
  • 5
  • 20
geedew
  • 1,368
  • 12
  • 16
  • This throws: `Uncaught SyntaxError: Invalid regular expression: /^[^@]+@[^@]+{2,}\.[^@]+{2,}$/: Nothing to repeat` when used in recent Chrome. – JimmyBlu Aug 08 '18 at 06:16
  • @JimmyBlu the `+` are uneeded... it should be: `/^[^@]+@[^@]{2,}\.[^@]{2,}$/` – Lenny Aug 24 '18 at 21:04
0

You can try this:

var booking_email = $('input[name=booking_email]').val();
if(booking_email.match(/^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/)) {
  // valid email
} else {
  // not valid
}
Ian Christian Myers
  • 1,270
  • 9
  • 14
  • 2
    You are too restrictive. For example you don't allow the + sign in the name part, used by gmail to tag mails. And before a test on the domain part is done, it has to be converted to punycode or you don't support IDN. http://stackoverflow.com/questions/3232/how-far-should-one-take-e-mail-address-validation/300862#300862 – some Feb 11 '11 at 04:58
0

Based on Ian Christian Myers reply before this, this answer adds + sign and extend to tld with more than 4 chars

function validateEmail(email) {
    const regex = /^[a-zA-Z0-9.+_-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,15}$/;
    return regex.test(email);
}
Nemesis19
  • 13
  • 5
0

<input type="email" name="email" required>

This should work I guess.

type = email will check for basic validations and required will check if the field is blank.

shawn bwz
  • 1
  • 1
-1

If you want to check only for Business Emails then try this :

<script type="text/javascript">
$(document).ready(function(e){
     $('#sendReq').click(function(){ 
     var email = $('#emailAddress').val();
     var reg = /^([\w-\.]+@(?!gmail.com)(?!yahoo.com)(?!hotmail.com)(?!yahoo.co.in)(?!aol.com)(?!abc.com)(?!xyz.com)(?!pqr.com)(?!rediffmail.com)(?!live.com)(?!outlook.com)(?!me.com)(?!msn.com)(?!ymail.com)([\w-]+\.)+[\w-]{2,4})?$/;
      if (reg.test(email)){
     return 0;
     }
     else{
     alert('Please Enter Business Email Address');
     return false;
     }
     });
    });
</script>
Abhishek Sengupta
  • 2,938
  • 1
  • 28
  • 35
-1

The is-email package on npm is super simple, if a little loose, just:

var matcher = /^[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])?)*$/;

function isEmail(string) {
  return matcher.test(string);
}

It was written by segment.io, who deal with a lot of emails.

rattray
  • 5,174
  • 1
  • 33
  • 27