515

What is the most elegant code to validate that a string is a valid email address?

Artemix
  • 1,899
  • 2
  • 21
  • 32
leora
  • 163,579
  • 332
  • 834
  • 1,328
  • 10
    http://www.regular-expressions.info/email.html – Noon Silk Sep 02 '09 at 01:04
  • 9
    Have a look at Phil Haack's article: "[I Knew How To Validate An Email Address Until I Read The RFC](http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx)" – Luke Quinane Sep 02 '09 at 01:07
  • there is many other important validations not just the string, it is better to check if the email is exists at this smtp server or the user is entering any email.. etc or to use API that will handles that for you to be sure the email is correct like http://ver-email.com – Amr Magdy May 25 '16 at 23:42
  • Best lnk from microsoft https://docs.microsoft.com/en-us/dotnet/standard/base-types/how-to-verify-that-strings-are-in-valid-email-format – Kishore Sahasranaman Dec 03 '17 at 07:14
  • you could use https://github.com/jstedfast/EmailValidation library. – Mohammad Reza Sadreddini Oct 06 '19 at 05:17

44 Answers44

872

What about this?

bool IsValidEmail(string email)
{
    try {
        var addr = new System.Net.Mail.MailAddress(email);
        return addr.Address == email;
    }
    catch {
        return false;
    }
}

Per Stuart's comment, this compares the final address with the original string instead of always returning true. MailAddress tries to parse a string with spaces into "Display Name" and "Address" portions, so the original version was returning false positives.


To clarify, the question is asking whether a particular string is a valid representation of an e-mail address, not whether an e-mail address is a valid destination to send a message. For that, the only real way is to send a message to confirm.

Note that e-mail addresses are more forgiving than you might first assume. These are all perfectly valid forms:

  • cog@wheel
  • "cogwheel the orange"@example.com
  • 123@$.xyz

For most use cases, a false "invalid" is much worse for your users and future proofing than a false "valid". Here's an article that used to be the accepted answer to this question (that answer has since been deleted). It has a lot more detail and some other ideas of how to solve the problem.

Providing sanity checks is still a good idea for user experience. Assuming the e-mail address is valid, you could look for known top-level domains, check the domain for an MX record, check for spelling errors from common domain names (gmail.cmo), etc. Then present a warning giving the user a chance to say "yes, my mail server really does allow as an email address."


As for using exception handling for business logic, I agree that is a thing to be avoided. But this is one of those cases where the convenience and clarity may outweigh the dogma.

Besides, if you do anything else with the e-mail address, it's probably going to involve turning it to a MailAddress. Even if you don't use this exact function, you will probably want to use the same pattern. You can also check for specific kinds of failure by catching different exceptions: null, empty, or invalid format.


--- Further reading ---

Documentation for System.Net.Mail.MailAddress

Explanation of what makes up a valid email address

Cogwheel
  • 20,820
  • 4
  • 42
  • 67
  • 12
    i don't think it works. i just tried it with simply a@a and it returned true. thats wrong. – Mouffette Oct 11 '09 at 05:59
  • 24
    Actually, that's not incorrect. a@a is a valid e-mail address. See http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx In fact, this method does return incorrect results if you use an address with quotes. – Cogwheel Oct 15 '09 at 13:37
  • 55
    +1: This is the best answer if you're using the `System.Net.Mail` classes to send mail, which you probably are if you're using .NET. We made the decision to use this type of validation simply because there is no point in us accepting email addresses - even valid ones - that we cannot send mail to. – Greg Beech Feb 25 '10 at 17:18
  • 25
    I don't recommend. It returns true: `IsValidEmail("this is not valid@email$com");` – Kakashi Dec 11 '11 at 18:33
  • 8
    @Kakashi: See the link I posted above. If you follow up by checking the RFC, you'll see "Any characters, or combination of bits (as octets), are permitted in DNS names. However, there is a preferred form that is required by most applications." In other words, it's only convention that makes that address invalid. You could always use the MailAddress object this code creates and further validate the Host part. – Cogwheel Jun 11 '12 at 05:30
  • 8
    The only reason I don't like this solution is that it relies on exception handling which is slow and bad practice in my book. Is there any way around this problem for this particular solution? I haven't been able to find one. – Dan Balthaser Oct 31 '12 at 22:02
  • 1
    I've ranted about using exceptions for business logic before, but I think in the context it's fine. It's a straightforward way of getting the job done without reinventing the wheel. If it turns out to be a performance issue, then I'd be inclined to go with Kibbee's suggestion. – Cogwheel Oct 31 '12 at 23:30
  • I don't like the idea to create an object in memory to validating something. @Dan Balthaser throwing exception is a good practice, but you should only catch them when required. – Bastien Vandamme Nov 26 '12 at 16:48
  • 1
    This one does no validation, and is useless. – Andreas Jan 22 '13 at 11:08
  • 4
    @Andreas I think you have a different idea of what "validation" means in the context of this question. Just because a string is a valid e-mail address, doesn't mean the e-mail address actually exists on a server somewhere. If that's not what you meant, then I suggest you read all the comments above and the article linked in the accepted answer. – Cogwheel Jan 31 '13 at 01:49
  • 3
    My first test of this code, IsValidEmail("xxx@u*.com") = true, which is obviously wrong. Not to mention using exceptions for control flow :( – Chad Grant Jul 18 '13 at 20:04
  • 9
    That's not obviously wrong if you read the spec. The question was about whether a particular string is a valid representation of an e-mail address, not whether that e-mail address is likely to exist on a server somewhere. – Cogwheel Jul 18 '13 at 21:29
  • 3
    I'm confused as to why everybody keeps saying `MailAddress` has it right. `"test email@hotmail.com"` come back as valid and I can't find anything in the spec that says you can have an unescaped space character in the local part of the name. – ta.speot.is Apr 24 '14 at 05:29
  • 3
    MailAddress may get some things wrong from the RFC, but most of the comments are about things it gets right that people assume are wrong. Either way, if you're in the .Net environment, this is the best way to ensure that you have an address that will be accepted by System.Net.Mail. – Cogwheel Apr 24 '14 at 16:49
  • 3
    -1 I have to agree with the others, that though this answer is technically right according to the RFC spec (actually it doesn't even do that according to the 2 comments above me), it is incorrect to the spirit of the original question since this answer considers valid so many addresses that would actually fail in reality. A standard RegEx is more appropriate to answer the spirit of the original question. – Doug S May 24 '14 at 20:44
  • 5
    -1 Besides using an `Exception` for validation, `System.Net.Mail.MailAddress` approves way too many string combinations that would fail in reality and are also wrong according to the RFC spec, such as `unescaped white space@fake$com`. – Doug S May 24 '14 at 21:13
  • 16
    A lot of the problems seem to be because MailAddress tries to parse the DisplayName out too, so "single space@domain.com" parses to DisplayName "single" and Address "space@domain.com". A fix for this is to: return (addr.Address == email); – Stuart May 27 '14 at 09:15
  • 1
    @DougS: Your second comment is addressed in the latest edit. Your first comment seems a bit odd... If you want to know whether an e-mail address will fail, the only sure way is to try sending it a message. You have to make a lot of assumptions about your environment to assume the addresses you think are invalid will always be invalid. As soon as one of those assumptions is broken you will have to fix your code. – Cogwheel May 27 '14 at 22:35
  • @Cog: I'm not saying I "want to know whether an e-mail address will fail" in advance, as I know that's practically impossible to know. My comment simply means that when we're trying to estimate whether a string looks like a good email address in the real world, this code fails a lot more often than a well-written RegEx. – Doug S May 29 '14 at 00:10
  • 5
    @DougS The real world is constantly changing. You can't predict where your code will be used in the future (maybe in an environment that uses internal domains that wouldn't exist on the public internet?), what TLDs will exist in the future, what kinds of addresses e-mail providers support, and on and on. For general applicability, the fewer assumptions you make in a function like this the better, imo. As an answer to the question posed, I fail to see how this is wrong. The asker didn't specify any of the assumptions you're making and accepted the most pedantic of all the given answers. – Cogwheel Jun 26 '14 at 18:37
  • 2
    @Cogwheel It's not a wrong answer, depending on the application. For the majority of applications, however, the negatives outweigh the elegance, and it's better to go with another solution such as RegEx. – Doug S Jun 27 '14 at 19:42
  • 19
    I like this; I don't get the compulsion to be more restrictive than the actual spec. False negatives are way worse than false positives ("what do you mean my e-mail is *invalid?*") – Casey Jul 30 '14 at 17:51
  • 10
    This is a great solution; why reinvent the wheel with code to determine what a valid email address is when you can instead just let .NET do it for you? Although I'm not inclined to trust Microsoft on much these days, this is one area where I'd gladly let them decide what's valid and what's not. If this doesn't fit your needs, don't cry about it in comments, just go use a RegEx. The fact remains, this will probably fit the needs of 90% of the people who Google "Validate email address in .NET". – Jim Oct 09 '14 at 19:54
  • 2
    I have read all the comments and found out that many of the users have declined your answer without even testing it or reading the specs. I checked space in the address, it doesn't accept spaces in the email address, but there are many comments complaining about spaces in comments. I would recommend using it. But the only drawback is that we don't have any idea about the code behind it, therefore it would be a bit wiser if one chooses to use a RegEx pattern. I have compared many results of your answer with the results of Haack's proposed RegEx. They have the same performance in many cases – Moh Jan 05 '15 at 09:05
  • According to the spec, your answer works better, but according to the conventions made on mail servers, Haack's RegEx is more realistic. – Moh Jan 05 '15 at 09:42
  • @MohammadAliannejadi I see what you're saying but i think that logic is reversed. When you're validating an e-mail address, it's almost certainly because someone gave it to you expecting you to send them e-mail. In that case, you definitely DON'T want to just cater to "the conventions made on mail servers." As others have stated, if you want to ensure that your message will be received, the only reliable way is to send a test message. – Cogwheel Feb 20 '15 at 07:59
  • 4
    @RezaRahmati - That is correct. It is completely acceptable for an email address to resolve to a machine that is accessible on a local network, but not part of a domain. I have a test VM simply called "mail", and I can send to address@mail just fine, as I should. The gist of this approach is that if you are going to send via an SmptClient instance, you are going to use a MailAddress. This simply provides a means to proactively capture addresses that MailAddress would have eventually reject before sending. A large percentage (not all) of the comments here are actually addressed in the RFC. – Joseph Ferris Sep 09 '16 at 03:53
  • 7
    Security remark: it is a well known DOS-like kind of attack, where a huge email expression provided to server, and it became busy forever while running email validation on that expression. Always check email string length BEFORE running 'IsEmailValid' method! – Illidan Nov 17 '16 at 05:48
  • 3
    And the maximum length of an email address is 254. See: https://stackoverflow.com/questions/386294/what-is-the-maximum-length-of-a-valid-email-address – Deantwo Jul 12 '17 at 13:29
  • This may seem like a good solution, the problem is it is expensive to catch exceptions. Run this side by side with a regex correctly implemented and you will see a difference. I had a similar issue with someone doing a try catch to determine if a string was null instead of just using string.IsNullOrWhitespace and the difference in performance is staggering. – AdamV Nov 16 '17 at 19:13
  • 2
    @AdamV my 2 cents : if you plan to check millions of e-mail addresses per second, then your comment is entirely valid. And I'm sure some people will actually want to do this. However, in most cases, this code will be used to check e-mails entered by a user on a website, and I believe even big websites will check only a few emails per second. Also, the purpose of an e-mail address is to send e-mails, which is probably 1 million times slower than throwing an exception. Bottom line is: don't optimize prematurely, unless the (supposedly) faster code is as simple, not error-prone, and maintainable. – youen Jan 17 '18 at 08:59
  • If using .NET 2.0 any non empty string returns true. I didn't test other versions. Why 2.0? Because Unity 3D. – Guney Ozsan Feb 01 '18 at 10:22
  • 3
    @GuneyOzsan It's not 2.0's fault it's Unity's. Unity's C# environment is very different from actual .Net – Cogwheel Feb 01 '18 at 21:26
  • @Cogwheel Thanks for the clarification. I didn't think it was a fault but I thought maybe earlier .Net was extremely more flexible about email address conditions. Unfortunately the unexpected cases of Unity can make such specialized things pretty hard time to time. Perhaps we should better call it C#-Unity. – Guney Ozsan Feb 02 '18 at 22:36
  • how expensive would be the exception if, say you expect more invalid emails than valid ones? would returning early by first checking for '@' character invalidate the solution? – waitforit Jul 20 '18 at 20:29
  • I've often used the MailAddress in this fashion but had a bit of a debate with my CTO about it's effectiveness. The main point of contention is: is this really expensive if you are say validating thousands of emails in a batch? Or would regex be a better option here? – The Senator Jan 18 '19 at 12:12
  • @TheSenator That's not a question you should try to answer a priori. This is an option that works. If you find that it doesn't perform well for your use case, then you can measure it against other approaches and pick the one that *actually* performs better for *your* use case. – Cogwheel Jan 23 '19 at 00:28
  • I use this method too. But i've put `if (string.IsNullOrEmpty(email) || email.Contains("@-") || email.Trim().Contains(" ")) return false;` above the try-catch. Because as far as I know an email address cannot contain a space or a dash right after the @. But `MailAddress` will return them true. See `IsValidEmail("fake@-false.com") > true` and `IsValidEmail("fake@fal se.com") > false` and `IsValidEmail("fa ke@false.com") > true` – VDWWD Apr 15 '19 at 07:58
  • @VDWWD The address portion can be quoted which means `@-` and space could appear in a valid address – Cogwheel May 07 '19 at 15:35
  • aaa a@com.com is not valid but this is not working. – Bilgin Kılıç Oct 18 '19 at 11:54
  • IMHO it is not valid, try "someone@somewhere..com" – Guy Cohen Mar 12 '20 at 04:19
  • This code is also returning true for me which is not correct. `var addr = new System.Net.Mail.MailAddress("govinda@gmailcom"); return addr.Address == email;` – Govinda Rajbhar Mar 26 '20 at 09:42
  • @GovindaRajbhar that is a valid email address. See the examples in the answer and the comments above. – Cogwheel Jul 07 '20 at 22:34
  • This code returns a false positive on e.g. 'myusername@gmail?com' – Mario Favere May 26 '21 at 12:34
266

This is an old question, but all the answers I've found on SO, including more recent ones, are answered similarly to this one. However, in .Net 4.5 / MVC 4 you can add email address validation to a form by adding the [EmailAddress] annotation from System.ComponentModel.DataAnnotations, so I was wondering why I couldn't just use the built-in functionality from .Net in general.

This seems to work, and seems to me to be fairly elegant:

using System.ComponentModel.DataAnnotations;

class ValidateSomeEmails
{
    static void Main(string[] args)
    {
        var foo = new EmailAddressAttribute();
        bool bar;
        bar = foo.IsValid("someone@somewhere.com");         //true
        bar = foo.IsValid("someone@somewhere.co.uk");       //true
        bar = foo.IsValid("someone+tag@somewhere.net");     //true
        bar = foo.IsValid("futureTLD@somewhere.fooo");      //true

        bar = foo.IsValid("fdsa");                          //false
        bar = foo.IsValid("fdsa@");                         //false
        bar = foo.IsValid("fdsa@fdsa");                     //false
        bar = foo.IsValid("fdsa@fdsa.");                    //false

        //one-liner
        if (new EmailAddressAttribute().IsValid("someone@somewhere.com"))
            bar = true;    
    }
}
imjosh
  • 4,167
  • 1
  • 16
  • 22
  • 1
    Looks like closing ) is missing in one-liner example – Artemix Jul 09 '13 at 15:51
  • 4
    Cool, although it's disappointing that MS can't make this agree with [their own documentation](http://msdn.microsoft.com/en-us/library/01escwtf(v=vs.110).aspx). This rejects js@proseware.com9 – Casey Jul 30 '14 at 18:27
  • 3
    If you use [EmailAddress] in your view model (as I do), this is a slick way to ensure that you use the same validation logic -- for better or worse -- in your code. – Bob.at.Indigo.Health Nov 02 '14 at 16:33
  • 14
    Note that `EmailAddressAttribute` is less permissive than `System.Net.Mail.MailAddress` - for instance, `MailAddress` accepts an address for a TLD. Just something to keep in mind if you need to be as permissive as possible. – Aaroninus Feb 04 '15 at 17:11
  • 3
    @hofnarwillie: yes, because that is a valid e-mail address. See the link in and comments on my answer. – Cogwheel Dec 10 '15 at 21:43
  • 2
    @Cogwheel, thanks, but your solution proves that the email address is valid according to the specification, not whether or not the email address will ever be a valid email in production environments - since no-one will ever have this email address: `.............@t`. I'm not trying to validate it theoretically, but rather ensure that my users register with a valid email address. I've since decided that the only way to do that is to send out a confirmation email. – hofnarwillie Dec 11 '15 at 16:08
  • 2
    @Cogwheel: All 36 of them? No. – hofnarwillie Dec 15 '15 at 17:27
  • 5
    @Cogwheel: if the answer lies somewhere in the comments it should probably be added to the main body of the answer. – hofnarwillie Dec 15 '15 at 17:28
  • 6
    @hofnarwillie: it is in the main body, but the comments elaborate. If your goal is to not anger your users then your validation shouldn't be any more restrictive than the spec. The only way to truly verify whether an e-mail is valid is to send a test message. – Cogwheel Dec 15 '15 at 23:40
  • 2
    @Cogwheel: That's a good idea. Thank you, I have now decided to send out a confirmation email. – hofnarwillie Dec 16 '15 at 08:56
  • This has the added benefit of working while targeting netstandard 1.6 which currently doesn't have access to System.Net.Mail – rushinge Apr 17 '17 at 21:24
  • 5
    Please note that `foo.IsValid(null);` returns `true`. – urig Jun 11 '17 at 10:01
  • 2
    @Casey If you look at the reference source for the attribute (https://github.com/Microsoft/referencesource/blob/master/System.ComponentModel.DataAnnotations/DataAnnotations/EmailAddressAttribute.cs), it says _"This attribute provides server-side email validation equivalent to jquery validate, and therefore shares the same regular expression"_. So I suppose jQuery e-mail validation (I assume https://jqueryvalidation.org/email-method/) is to blame. – Ohad Schneider Jul 15 '17 at 11:00
  • @Aaroninus can you provide a specific example of an e-mail address this attribute rejects but `System.Net.Mail.MailAddress` accepts? – Ohad Schneider Jul 15 '17 at 11:01
  • 2
    @OhadSchneider An email address with only a TLD, e.g. _example@com_ – Aaroninus Jul 17 '17 at 11:45
  • [Here's the actual source for EmailAddressAttribute](http://referencesource.microsoft.com/#System.ComponentModel.DataAnnotations/DataAnnotations/EmailAddressAttribute.cs). The regex and options can be found on lines 54 and 55. – Bacon Bits Sep 22 '17 at 13:03
  • for me this line returning true which is not correct `var result = new EmailAddressAttribute().IsValid("govinda@gmailcom");` – Govinda Rajbhar Mar 26 '20 at 09:40
  • 1
    Thanks I like the 1 liner solution, I used it in a method I added in my data validation class. 1 improvement I would suggest for your answer is changing the variables name "foo" to "emailTester" and "bar" to "valid", or similar variable names that are more descriptive. – SendETHToThisAddress Jun 02 '20 at 07:26
  • 2
    Also note that .Net Core implementation seems to be wildly different and way simpler than .Net Framework one: https://source.dot.net/#System.ComponentModel.Annotations/System/ComponentModel/DataAnnotations/EmailAddressAttribute.cs,c3ae85dfd8a9f58c – Hoffs Oct 22 '20 at 07:36
67

I use this single liner method which does the work for me-

using System.ComponentModel.DataAnnotations;
public bool IsValidEmail(string source)
{
    return new EmailAddressAttribute().IsValid(source);
}

Per the comments, this will "fail" if the source (the email address) is null.

public static bool IsValidEmailAddress(this string address) => address != null && new EmailAddressAttribute().IsValid(address);
Marc.2377
  • 5,840
  • 5
  • 43
  • 75
Manik Arora
  • 4,345
  • 1
  • 22
  • 45
  • 1
    This doesn't work for me; I get, "'Data Annotations' does not exist...are you missing an assembly reference?" Which reference do I need to add? – B. Clay Shannon Feb 12 '16 at 17:17
  • This will return true if source is null. See https://msdn.microsoft.com/en-us/library/hh192424 "true if the specified value is valid or null; otherwise, false." – jao Feb 11 '17 at 13:12
  • 2
    A better version: `public static Boolean IsValidMailAddress(this String pThis) => pThis == null ? false : new EmailAddressAttribute().IsValid(pThis);` – Sebastian Hofmann Mar 07 '18 at 13:04
  • 7
    Or even better: `public static bool IsValidEmailAddress(this string address) => address != null && new EmailAddressAttribute().IsValid(address);` – Patrik Melander Jun 19 '18 at 08:46
  • Or even better better: `public static bool IsValidEmailAddress(this string address) => !(address is null) && new EmailAddressAttribute().IsValid(address);` :-) – Jon49 Jan 14 '19 at 14:22
  • 1
    I don't think this extension method should silently return `false` for null strings. That's why I propose the (even better better)++ version: `public static bool IsValidEmailAddress(this string address) => new EmailAddressAttribute().IsValid(address ?? throw new ArgumentNullException());`. I'll now go and found the Reformed Church of the Even Better Better Versionists. – Marc.2377 May 24 '19 at 19:39
  • Source code here https://github.com/microsoft/referencesource/blob/master/System.ComponentModel.DataAnnotations/DataAnnotations/EmailAddressAttribute.cs It uses Regex internally. And uses the same Regex as jquery – Student222 Sep 13 '19 at 01:06
43

.net 4.5 added System.ComponentModel.DataAnnotations.EmailAddressAttribute

You can browse the EmailAddressAttribute's source, this is the Regex it uses internally:

const string pattern = @"^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$";
Thomas Ayoub
  • 27,208
  • 15
  • 85
  • 130
Chad Grant
  • 40,129
  • 8
  • 59
  • 76
  • 2
    Unfortunately the EmaillAddressAttribute allows Ñ which is not a valid character for email – B Z Sep 06 '13 at 18:06
  • 16
    @BZ Yes it is. Why do you think it isn't? – Casey Jul 30 '14 at 18:31
  • @Chad Grant: This is a C# version. Can you please provide a VB.Net one. Because that will escape characers like \\ to \ or you can provide a string verbatim one. – Nikhil Agrawal Oct 05 '15 at 06:08
  • 4
    This works, but don't forget `RegexOptions.IgnoreCase` because this pattern does not allow capital letters explicitly! – Chris May 02 '17 at 14:12
  • 1
    Note that Regex is very deliberate: _"This attribute provides server-side email validation equivalent to jquery validate, and therefore shares the same regular expression"._ – Ohad Schneider Jul 15 '17 at 11:25
41

I took Phil's answer from #1 and created this class. Call it like this: bool isValid = Validator.EmailIsValid(emailString);

Here is the class:

using System.Text.RegularExpressions;

public static class Validator
{

    static Regex ValidEmailRegex = CreateValidEmailRegex();

    /// <summary>
    /// Taken from http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx
    /// </summary>
    /// <returns></returns>
    private static Regex CreateValidEmailRegex()
    {
        string validEmailPattern = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|"
            + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)"
            + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";

        return new Regex(validEmailPattern, RegexOptions.IgnoreCase);
    }

    internal static bool EmailIsValid(string emailAddress)
    {
        bool isValid = ValidEmailRegex.IsMatch(emailAddress);

        return isValid;
    }
}
David Silva Smith
  • 10,265
  • 10
  • 62
  • 87
  • 5
    Just a small one, but I would use: return (!string.IsNullOrEmpty(emailAddress)) && ValidEmailRegex.IsMatch(emailAddress); – Marc Nov 15 '13 at 14:16
  • This is just horror :) – Alexandru Dicu Oct 20 '16 at 08:36
  • this will not validate emails with 1 character domain. i.e: bla@a.com – Владимiръ Nov 24 '20 at 22:25
  • @Владимiръ did you run the code? Last time someone said it didn't work, I fired up a coding environment and it did validate properly. I haven't used C# in about 8 years and I'm genuinely curious if you know it doesn't work or if you are reading the code and saying it doesn't work. – David Silva Smith Nov 25 '20 at 15:45
32

Personally, I would say that you should just make sure there is an @ symbol in there, with possibly a . character. There's many regexes you could use of varying correctness, but I think most of these leave out valid email addresses, or let invalid ones through. If people want to put in a fake email address, they will put in a fake one. If you need to verify that the email address is legit, and that the person is in control of that email address, then you will need to send them an email with a special coded link so they can verify that it indeed is a real address.

Kibbee
  • 62,900
  • 26
  • 139
  • 178
  • 6
    I personally think you should do a bit more validation than that. Someone's bound to try Bobby Table's email address or worse. – Luke Quinane Sep 02 '09 at 01:20
  • 31
    What's wrong with bobby table's email address if you're using prepared statements. We're talking about valid email addresses, not other things that have nothing to do with what constitues a valid email address, like how to properly do SQL queries so that you don't get SQL injection problems. – Kibbee Sep 02 '09 at 02:06
  • I guess you don't know what someone will put in there but a malicious person knows that the value may eventually be fed into your mail system. I'd just prefer to go defense in depth and be a bit stricter. – Luke Quinane Sep 02 '09 at 02:17
  • 10
    That's for the mail system to worry about. I wouldn't go around rejecting perfectly valid email addresses just because it could be a security issue with some other system. If all your email server needs is a malformed email address to cause security problems, you should probably switch to another server. – Kibbee Sep 02 '09 at 15:44
  • 4
    Defence in depth only works if each level of your security onion is not rotten. One rotten layer means you spoil the whole onion. Rejecting "foo@example.com.au" because you want to defend against vulnerabilities in Sun's µ-law encoding doesn't make sense, does it? Don't laugh, it's happened to me. The reason I am here commenting is that Medicare Australia doesn't allow ".au" addresses, only ".com". Also read Mark Swanson, "How not to validate email, ", http://mdswanson.com/blog/2013/10/14/how-not-to-validate-email-addresses.html – ManicDee Nov 22 '13 at 05:21
  • @ManicDee *"Also read Mark Swanson, "How not to validate email"* -- **"Or maybe you will find a regular expression that looks something like `^[_a-z0-9-]+(\.[_a-z0-9-]omg-whyyyyy$`. ... So what should you do instead? Just check for the existence of @. Every email address will have at least one of them and it is trivially easy to write this code."** The buttoned up coder in me is trying to resist, but the rest is surprisingly convincingly arguing that anything else is a [sad tragedy of micro-optimization](https://blog.codinghorror.com/the-sad-tragedy-of-micro-optimization-theater/). – ruffin Oct 11 '16 at 18:47
  • There's a trade-off here between protecting the user from a silly mistake (not realizing the field is an e-mail address, or making some typo) and the chance you user has some super-weird address that gets rejected by standard validators like `EmailAddressAttribute` and `System.Net.Mail.MailAddress`. The way I see it, a person whose address is rejected by those is seriously screwed and my site is going to be the last of his troubles. Maybe a bank will see it otherwise. Of course if you want to go to the trouble of a coded link your answer is probably the best bet (without checking for `.` even) – Ohad Schneider Jul 15 '17 at 11:24
  • One more easy check worth adding is `3<=length<=254` (remember `a@a` is valid) – Ohad Schneider Jul 15 '17 at 14:11
  • What's nice about this approach is we don't need another library reference, ie `System.Net.Mail` – gdbj Feb 20 '18 at 20:57
19

Short and accurate code

string Email = txtEmail.Text;
if (Email.IsValidEmail())
{
   //use code here 
}

public static bool IsValidEmail(this string email)
{
  string pattern = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|" + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)" + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";    
  var regex = new Regex(pattern, RegexOptions.IgnoreCase);    
  return regex.IsMatch(email);
}
Naveen
  • 1,186
  • 1
  • 13
  • 35
  • 2
    Thanks for the solution – Jack Gajanan May 24 '18 at 13:39
  • I had to change public static bool IsValidEmail(this string email) to public static bool IsValidEmail(string email) to avoid THIS: https://stackoverflow.com/questions/10412233/extension-method-must-be-defined-in-non-generic-static-class – Goner Doug Apr 29 '19 at 23:04
  • @Goner Doug, this functionlity will work like this.(bool flag = EmailAddress.IsValidEmail()) – Naveen Apr 30 '19 at 05:44
  • 2
    the "THIS" needed to be removed to avoid causing compiler issues when added to my form. – Goner Doug May 01 '19 at 15:20
  • @Goner Doug, Its functionlity will work like this. string email = "abc@xyz.com"; if (email.IsValidEmail()){ return false; }else { return true;} – Naveen Jul 16 '19 at 07:04
18

I think the best way is as follow:

    public static bool EmailIsValid(string email)
    {
        string expression = "\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";

        if (Regex.IsMatch(email, expression))
        {
            if (Regex.Replace(email, expression, string.Empty).Length == 0)
            {
                return true;
            }
        }
        return false;
    }

You can have this static function in a general class.

Ruben Pita
  • 53
  • 9
Poyson1
  • 373
  • 4
  • 13
16

The most elegant way is to use .Net's built in methods.

These methods:

  • Are tried and tested. These methods are used in my own professional projects.

  • Use regular expressions internally, which are reliable and fast.

  • Made by Microsoft for C#. There's no need to reinvent the wheel.

  • Return a bool result. True means the email is valid.

For users of .Net 4.5 and greater

Add this Reference to your project:

System.ComponentModel.DataAnnotations

Now you can use the following code:

(new EmailAddressAttribute().IsValid("youremailhere@test.test"));

Example of use

Here are some methods to declare:

protected List<string> GetRecipients() // Gets recipients from TextBox named `TxtRecipients`
{
    List<string> MethodResult = null;

    try
    {
        List<string> Recipients = TxtRecipients.Text.Replace(",",";").Replace(" ", "").Split(';').ToList();

        List<string> RecipientsCleaned = new List<string>();

        foreach (string Recipient in RecipientsCleaned)
        {
            if (!String.IsNullOrWhiteSpace(Recipient))
            {
                RecipientsNoBlanks.Add(Recipient);

            }

        }

        MethodResult = RecipientsNoBlanks;

    }
    catch//(Exception ex)
    {
        //ex.HandleException();
    }

    return MethodResult;

}


public static bool IsValidEmailAddresses(List<string> recipients)
{
    List<string> InvalidAddresses = GetInvalidEmailAddresses(recipients);

    return InvalidAddresses != null && InvalidAddresses.Count == 0;

}

public static List<string> GetInvalidEmailAddresses(List<string> recipients)
{
    List<string> MethodResult = null;

    try
    {
        List<string> InvalidEmailAddresses = new List<string>();

        foreach (string Recipient in recipients)
        {
            if (!(new EmailAddressAttribute().IsValid(Recipient)) && !InvalidEmailAddresses.Contains(Recipient))
            {
                InvalidEmailAddresses.Add(Recipient);

            }

        }

        MethodResult = InvalidEmailAddresses;

    }
    catch//(Exception ex)
    {
        //ex.HandleException();

    }

    return MethodResult;

}

...and code demonstrating them in action:

List<string> Recipients = GetRecipients();

bool IsValidEmailAddresses = IsValidEmailAddresses(Recipients);

if (IsValidEmailAddresses)
{
    //Emails are valid. Your code here

}
else
{
    StringBuilder sb = new StringBuilder();

    sb.Append("The following addresses are invalid:");

    List<string> InvalidEmails = GetInvalidEmailAddresses(Recipients);

    foreach (string InvalidEmail in InvalidEmails)
    {
        sb.Append("\n" + InvalidEmail);

    }

    MessageBox.Show(sb.ToString());

}

In addition, this example:

  • Extends beyond the spec since a single string is used to contain 0, one or many email addresses sperated by a semi-colon ;.
  • Clearly demonstrates how to use the IsValid method of the EmailAddressAttribute object.

Alternative, for users of a version of .Net less than 4.5

For situations where .Net 4.5 is not available, I use the following solution:

Specifically, I use:

public static bool IsValidEmailAddress(string emailAddress)
{
    bool MethodResult = false;

    try
    {
        MailAddress m = new MailAddress(emailAddress);

        MethodResult = m.Address == emailAddress;

    }
    catch //(Exception ex)
    {
        //ex.HandleException();

    }

    return MethodResult;

}

public static List<string> GetInvalidEmailAddresses(List<string> recipients)
{
    List<string> MethodResult = null;

    try
    {
        List<string> InvalidEmailAddresses = new List<string>();

        foreach (string Recipient in recipients)
        {
            if (!IsValidEmail(Recipient) && !InvalidEmailAddresses.Contains(Recipient))
            {
                InvalidEmailAddresses.Add(Recipient);

            }

        }

        MethodResult = InvalidEmailAddresses;

    }
    catch //(Exception ex)
    {
        //ex.HandleException();

    }

    return MethodResult;

}
WonderWorker
  • 7,388
  • 3
  • 52
  • 71
  • 1
    @ThomasAyoub I haven't seen an EmailAddressAttribute answer, and no answer that uses new MailAddress() with a check on input == .Address so I think its pretty useful. Without reading comments the accepted answer is pretty wrong. new MailAddress("Foobar Some@thing.com") proves that. – Jan Sep 18 '17 at 13:56
  • @Jan fwiw, [Manik](https://stackoverflow.com/a/33931538/1028230) beat Knickerless to the `EmailAddressAttribute` by just under four months, though this one does catch the `null` issue. – ruffin Feb 27 '18 at 18:07
7

To be honest, in production code, the best I do is check for an @ symbol.

I'm never in a place to be completely validating emails. You know how I see if it was really valid? If it got sent. If it didn't, it's bad, if it did, life's good. That's all I need to know.

Noon Silk
  • 51,625
  • 6
  • 84
  • 103
6

I find this regex to be a good trade off between checking for something more than just the @ mark, and accepting weird edge cases:

^[^@\s]+@[^@\s]+(\.[^@\s]+)+$

It will at least make you put something around the @ mark, and put at least a normal looking domain.

Matthew Lock
  • 11,495
  • 11
  • 84
  • 122
4

Email address validation is not as easy as it might seem. It's actually theoretically impossible to fully validate an email address using just a regular expression.

Check out my blog post about it for a discussion on the subject and a F# implementation using FParsec. [/shameless_plug]

Mauricio Scheffer
  • 96,120
  • 20
  • 187
  • 273
4

Here's my answer -- Phil's solution fails for single letter domains like "someone@q.com". Believe it or not, that's used =) (goes to centurylink, for instance).

Phil's answer is also going to work only with PCRE standard... so C# will take it, but javascript is going to bomb. It's too complex for javascript. So you can't use Phil's solution for mvc validation attributes.

Here's my regex. It'll work nicely with MVC validation attributes.
- Everything before the @ is simplified, so that at least javascript will work. I'm okay relaxing validation here as long as exchange server doesn't give me a 5.1.3. - Everything after the @ is Phil's solution modified for single letter domains.

public const string EmailPattern =
        @"^\s*[\w\-\+_']+(\.[\w\-\+_']+)*\@[A-Za-z0-9]([\w\.-]*[A-Za-z0-9])?\.[A-Za-z][A-Za-z\.]*[A-Za-z]$";

For people suggesting using system.net.mail MailMessage(), that thing is WAY to flexible. Sure, C# will accept the email, but then exchange server will bomb with 5.1.3 runtime error as soon as you try to send the email.

Ralph N
  • 3,952
  • 8
  • 25
  • 36
  • that seems to be the best most thoughtful / reasonable / realworld answer, thanks Ralph! – Fattie Mar 24 '14 at 19:03
  • this is the best answer so far! I can't believe a bad solution that accepts `basket@ball` as a valid email address has gained the correct answer as well as all those upvotes. Thanks anyway! – disasterkid Aug 28 '15 at 08:27
  • Thanks this is the best solution and should be accepted answer. – Bat_Programmer Jul 16 '18 at 01:01
4

I just want to point out, that there has been a recent addition to the .NET documentation regarding email validation, also utilitzing Regex operations. A thorough explanation to their implementation can be found there.

https://docs.microsoft.com/en-us/dotnet/standard/base-types/how-to-verify-that-strings-are-in-valid-email-format

For convenience, here is a list of their test results:

//       Valid: david.jones@proseware.com
//       Valid: d.j@server1.proseware.com
//       Valid: jones@ms1.proseware.com
//       Invalid: j.@server1.proseware.com
//       Valid: j@proseware.com9
//       Valid: js#internal@proseware.com
//       Valid: j_9@[129.126.118.1]
//       Invalid: j..s@proseware.com
//       Invalid: js*@proseware.com
//       Invalid: js@proseware..com
//       Valid: js@proseware.com9
//       Valid: j.s@server1.proseware.com
//       Valid: "j\"s\""@proseware.com
//       Valid: js@contoso.中国
Manuel Fuchs
  • 320
  • 3
  • 9
3

If you really and I mean really want to know if an email address is valid...ask the mail exchanger to prove it, no regex needed. I can provide the code if requested.

General steps are as follows: 1. does email address have a domain name part? (index of @ > 0) 2. using a DNS query ask if domain has a mail exchanger 3. open tcp connection to mail exchanger 4. using the smtp protocol, open a message to the server using the email address as the reciever 5. parse the server's response. 6. quit the message if you made it this far, everything is good.

This is as you can imagine, very expensive time wise and relies on smtp, but it does work.

Joe Caffeine
  • 828
  • 5
  • 10
  • Did you create fakes, stubs and/or mocks for those interfaces? – Mark A Sep 20 '12 at 20:25
  • 1
    That won't work. The smtp protocol to verify an email address has LONG been deprecated/not used. It is considered bad practice to enable that on mail servers since spammers use that functionality. – Chad Grant Sep 09 '13 at 20:15
  • I'll keep your suggestion up to point 2. Way more future-proof than checking for a known domain name pattern. – Simone May 23 '17 at 08:35
  • Nitpicking, but define *"has a mail exchanger"*? If no MX records exist, SMTP should fall back to the A/AAAA record, as per RFC2821/5321. If an MX record does exist, it still might not indicate a mail exchanger exists (RFC7505). Really, the only way is to send them a mail with a call-to-action link, and wait for them to reply... – jimbobmcgee May 31 '17 at 11:40
2
For the simple email like goerge@xxx.com, below code is sufficient. 

 public static bool ValidateEmail(string email)
        {
            System.Text.RegularExpressions.Regex emailRegex = new System.Text.RegularExpressions.Regex(@"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$");
            System.Text.RegularExpressions.Match emailMatch = emailRegex.Match(email);
            return emailMatch.Success;
        }
user2211290
  • 874
  • 8
  • 16
2

In case you are using FluentValidation you could write something as simple as this:

public cass User
{
    public string Email { get; set; }
}

public class UserValidator : AbstractValidator<User>
{
    public UserValidator()
    {
        RuleFor(x => x.Email).EmailAddress().WithMessage("The text entered is not a valid email address.");
    }
}

// Validates an user. 
var validationResult = new UserValidator().Validate(new User { Email = "açflkdj" });

// This will return false, since the user email is not valid.
bool userIsValid = validationResult.IsValid;
Ulysses Alves
  • 1,960
  • 1
  • 18
  • 32
2

a little modification to @Cogwheel answer

public static bool IsValidEmail(this string email)
{
  // skip the exception & return early if possible
  if (email.IndexOf("@") <= 0) return false;

  try
  {
    var address = new MailAddress(email);
    return address.Address == email;
  }
  catch
  {
    return false;
  }
}
waitforit
  • 2,501
  • 3
  • 25
  • 54
  • This doesn't seem to help... `Console.WriteLine(MailAddress("asdf@asdf.").Address);` outputs "asdf@asdf.", which is not valid. – Langdon Oct 01 '18 at 15:25
  • .net seems to have its own definition of valid. related [discussion](https://stackoverflow.com/q/49153319/7379424) – waitforit Oct 01 '18 at 20:14
2

There are a lot of strong answers here. However, I recommend that we take a step back. @Cogwheel answers the question https://stackoverflow.com/a/1374644/388267. Nevertheless, it could be costly in a bulk validation scenario, if many of the email address being validated are invalid. I suggest that we employ a bit of logic before we enter into his try-catch block. I know that the following code could be written using RegEx but that could be costly for new developers to understand. This is my twopence worth:

    public static bool IsEmail(this string input)
    {
        if (string.IsNullOrWhiteSpace(input)) return false;

        // MUST CONTAIN ONE AND ONLY ONE @
        var atCount = input.Count(c => c == '@');
        if (atCount != 1) return false;

        // MUST CONTAIN PERIOD
        if (!input.Contains(".")) return false;

        // @ MUST OCCUR BEFORE LAST PERIOD
        var indexOfAt = input.IndexOf("@", StringComparison.Ordinal);
        var lastIndexOfPeriod = input.LastIndexOf(".", StringComparison.Ordinal);
        var atBeforeLastPeriod = lastIndexOfPeriod > indexOfAt;
        if (!atBeforeLastPeriod) return false;

        // CODE FROM COGWHEEL'S ANSWER: https://stackoverflow.com/a/1374644/388267 
        try
        {
            var addr = new System.Net.Mail.MailAddress(input);
            return addr.Address == input;
        }
        catch
        {
            return false;
        }
    }
CarneyCode
  • 3,451
  • 3
  • 24
  • 45
2

The most voted answer from @Cogwheel is best answer however i have tried to implement trim() string method so it will trim all user white space from string start to end. Check the code bellow for full example-

bool IsValidEmail(string email)
{
    try
    {
        email = email.Trim();
        var addr = new System.Net.Mail.MailAddress(email);
        return addr.Address == email;
    }
    catch
    {
        return false;
    }
}
Liakat
  • 961
  • 1
  • 9
  • 20
  • The risk of this is that you are validating a different e-mailaddress than the source, leaving you to think you can mail to the (in this case) untrimmed version of the specified e-mailaddress. A better approach would be to make a seperate method `SanitizeEmail(string email)`, using the result of that method to validate and send the email to. – Marco de Zeeuw Apr 09 '19 at 12:18
2

Generally speaking, a regular expression to validate email addresses is not an easy thing to come up with; at the time of this writing, the syntax of an email address must follow a relatively high number of standards and implementing all of them within a regular expression is practically unfeasible!

I highly suggest you to try our EmailVerify.NET, a mature .NET library which can validate email addresses following all of the current IETF standards (RFC 1123, RFC 2821, RFC 2822, RFC 3696, RFC 4291, RFC 5321 and RFC 5322), tests the related DNS records, checks if the target mailboxes can accept messages and can even tell if a given address is disposable or not.

Disclaimer: I am the lead developer for this component.

Efran Cobisi
  • 4,636
  • 17
  • 21
  • Impressive! "Next, it tries to contact the mail exchanger responsible for the given email address and begins a fake SMTP dialog with that server, emulating a real mail server. This way it ensures that the server can handle emails for the address. Many SMTP servers actually give back false positive answers as a protection against spammers: to overcome this issue, EmailVerify for .NET finally attempts to query the target mail exchanger multiple times with different fabricated addresses. " – Matthew Lock Oct 22 '15 at 03:34
  • Thanks, @MatthewLock ;) – Efran Cobisi Oct 23 '15 at 10:05
  • Nice, but I only see paid editions. Any plans for a community/OpenSource edition? – Ohad Schneider Jul 15 '17 at 11:28
  • 1
    @OhadSchneider Yes: we are offering a free version of our email validation technology by way of Verifalia, our SaaS [email verification service](http://verifalia.com/developers). Verifalia comes with free and open-source SDKs for the major software development platforms, including [.NET](https://github.com/verifalia/verifalia-csharp-sdk). – Efran Cobisi Jul 16 '17 at 14:26
1
private static bool IsValidEmail(string emailAddress)
{
    const string validEmailPattern = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|"
                                     + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)"
                                     + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";

    return new Regex(validEmailPattern, RegexOptions.IgnoreCase).IsMatch(emailAddress);
}
ErwanLent
  • 566
  • 7
  • 14
1

Check email string is right format or wrong format by System.Text.RegularExpressions:

    public static bool IsValidEmailId(string InputEmail)
    {
        Regex regex = new Regex(@"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$");
        Match match = regex.Match(InputEmail);
        if (match.Success)
            return true;
        else
            return false;
    }

    protected void Email_TextChanged(object sender, EventArgs e)
    {
        String UserEmail = Email.Text;
        if (IsValidEmailId(UserEmail))
        {
            Label4.Text = "This email is correct formate";
        }
        else
        {
            Label4.Text = "This email isn't correct formate";
        }
    }
rktuxyn
  • 593
  • 9
  • 18
1

/Using the Internal Regex used in creating the "new EmailAddressAttribute();" component in .Net4.5 >>> using System.ComponentModel.DataAnnotations; //To Validate an Email Address......Tested and Working.

public bool IsEmail(string email)
{
    if (String.IsNullOrEmpty(email))
    {   return false;  }
    try
    {
        Regex _regex = new Regex("^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])" +
                "+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)" +
                "((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|" +
                "[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\u" +
                "FDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|" +
                "(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|" +
                "[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900" +
                "-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFF" +
                "EF])))\\.?$", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled);
        return _regex.IsMatch(email);
    }
    catch (RegexMatchTimeoutException)
    {
        return false;
    }
}

Also, You can use this:

http://msdn.microsoft.com/en-us/library/01escwtf(v=vs.110).aspx

  • it says true for this email : "fulya_42_@hotmail.coö" and it throws error at mandrill api – MonsterMMORPG May 26 '15 at 11:20
  • 1
    First, the email is valid w.r.t. example@example.co or example@example.com....The email has all valid string and criterial except for the last character " ö " and you can easily add a simple condition to validate such character. Second, am not sure about that mandrill api error, you might want to verify your method of usage bcos I have used this validation on some other environment / api's and its been good to me. – Aina Ademola C May 29 '15 at 13:24
1

I succinctified Poyson 1's answer like so:

public static bool IsValidEmailAddress(string candidateEmailAddr)
{
    string regexExpresion = "\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";
    return (Regex.IsMatch(candidateEmailAddr, regexExpresion)) && 
           (Regex.Replace(candidateEmailAddr, regexExpresion, string.Empty).Length == 0);
}
B. Clay Shannon
  • 1,055
  • 124
  • 399
  • 759
1

Here is an answer to your question for you to check.

using System;
using System.Globalization;
using System.Text.RegularExpressions;

public class RegexUtilities
{    
   public bool IsValidEmail(string strIn)
   {
       if (String.IsNullOrEmpty(strIn))
       {
          return false;

       }

       // Use IdnMapping class to convert Unicode domain names.

       try 
       {
          strIn = Regex.Replace(strIn, @"(@)(.+)$", this.DomainMapper, RegexOptions.None, TimeSpan.FromMilliseconds(200));

       }
       catch (RegexMatchTimeoutException) 
       {
           return false;

       }

       if (invalid)
       {
           return false;

       }

       // Return true if strIn is in valid e-mail format.    

       try 
       {
          return Regex.IsMatch(strIn, @"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|       [-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$", RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250));

       }
       catch (RegexMatchTimeoutException) 
       {
          return false;

       }

   }


   private string DomainMapper(Match match)
   {
      // IdnMapping class with default property values.

      IdnMapping idn = new IdnMapping();

      string domainName = match.Groups[2].Value;

      try 
      {
         domainName = idn.GetAscii(domainName);

      }
      catch (ArgumentException) 
      {
         invalid = true;

      }

      return match.Groups[1].Value + domainName;

   }

}
WonderWorker
  • 7,388
  • 3
  • 52
  • 71
Parsa Karami
  • 642
  • 1
  • 7
  • 26
1

Simple way to identify the emailid is valid or not.

public static bool EmailIsValid(string email)
{
        return Regex.IsMatch(email, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
}
1

There is culture problem in regex in C# rather then js. So we need to use regex in US mode for email check. If you don't use ECMAScript mode, your language special characters are imply in A-Z with regex.

Regex.IsMatch(email, @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9_\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$", RegexOptions.ECMAScript)
mkysoft
  • 4,255
  • 1
  • 16
  • 26
1

I ended up using this regex, as it successfully validates commas, comments, Unicode characters and IP(v4) domain addresses.

Valid addresses will be:

" "@example.org

(comment)test@example.org

тест@example.org

ტესტი@example.org

test@[192.168.1.1]

 public const string REGEX_EMAIL = @"^(((\([\w!#$%&'*+\/=?^_`{|}~-]*\))?[^<>()[\]\\.,;:\s@\""]+(\.[^<>()[\]\\.,;:\s@\""]+)*)|(\"".+\""))(\([\w!#$%&'*+\/=?^_`{|}~-]*\))?@((\[[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,}))$";
Community
  • 1
  • 1
d.popov
  • 3,777
  • 1
  • 32
  • 43
1

A simple one without using Regex (which I don't like for its poor readability):

bool IsValidEmail(string email)
{
    string emailTrimed = email.Trim();

    if (!string.IsNullOrEmpty(emailTrimed))
    {
        bool hasWhitespace = emailTrimed.Contains(" ");

        int indexOfAtSign = emailTrimed.LastIndexOf('@');

        if (indexOfAtSign > 0 && !hasWhitespace)
        {
            string afterAtSign = emailTrimed.Substring(indexOfAtSign + 1);

            int indexOfDotAfterAtSign = afterAtSign.LastIndexOf('.');

            if (indexOfDotAfterAtSign > 0 && afterAtSign.Substring(indexOfDotAfterAtSign).Length > 1)
                return true;
        }
    }

    return false;
}

Examples:

  • IsValidEmail("@b.com") // false
  • IsValidEmail("a@.com") // false
  • IsValidEmail("a@bcom") // false
  • IsValidEmail("a.b@com") // false
  • IsValidEmail("a@b.") // false
  • IsValidEmail("a b@c.com") // false
  • IsValidEmail("a@b c.com") // false
  • IsValidEmail("a@b.com") // true
  • IsValidEmail("a@b.c.com") // true
  • IsValidEmail("a+b@c.com") // true
  • IsValidEmail("a@123.45.67.89") // true

It is meant to be simple and therefore it doesn't deal with rare cases like emails with bracketed domains that contain spaces (typically allowed), emails with IPv6 addresses, etc.

aBertrand
  • 189
  • 1
  • 7
1

Based on the answer of @Cogwheel i want to share a modified solution that works for SSIS and the "Script Component":

  1. Place the "Script Component" into your Data Flow connect and then open it.
  2. In the section "Input Columns" set the field that contains the E-Mail Adresses to "ReadWrite" (in the example 'fieldName').
  3. Switch back to the section "Script" and click on "Edit Script". Then you need to wait after the code opens.
  4. Place this code in the right method:

    public override void Input0_ProcessInputRow(Input0Buffer Row)
    {
        string email = Row.fieldName;
    
        try
        {
            System.Net.Mail.MailAddress addr = new System.Net.Mail.MailAddress(email);
            Row.fieldName= addr.Address.ToString();
        }
        catch
        {
            Row.fieldName = "WRONGADDRESS";
        }
    }
    

Then you can use a Conditional Split to filter out all invalid records or whatever you want to do.

user3772108
  • 812
  • 2
  • 9
  • 28
1

Another Regex Match answer :

   /// <summary>
   /// Validates the email input
   /// </summary>
   internal static bool ValidateEmail(string _emailAddress)
   { 

        string _regexPattern = @"^(([\w-]+\.)+[\w-]+|([a-zA-Z]{1}|[\w-]{2,}))@"
                + @"((([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\."
                + @"([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])){1}|"
                + @"([a-zA-Z]+[\w-]+\.)+[a-zA-Z]{2,4})$";

        return (string.IsNullOrEmpty(_emailAddress) == false && System.Text.RegularExpressions.Regex.IsMatch(_emailAddress, _regexPattern))
            ? true
            : false;
    }
karsnen
  • 113
  • 2
  • 10
1

As mentioned in many answers, the domain of email addresses is complex. I would strongly discourage the use of a regex in this case. Those who match (most) cases are extremely complex to read and therefor to maintain. Furthermore, the still have difficulties supporting all cases, and are slow.

Microsoft's EmailAddress class helps a bit in that respect, but is not perfect either, I would argue. For an open source project I gave it try some years ago, by using a customized EmailParser.

That is used in [EmailAddress]https://github.com/Qowaiv/Qowaiv/blob/master/src/Qowaiv/EmailAddress.cs).

By using this approach, you're not only to validate email addresses, but also by cleaning out multiple formats of display names, getting rid of the mailto:-prefix, and normalizing domain literals based on IP-addresses, and lowercasing everything (note that the local part officially is case sensitive).

Scenario's your solution should support (and the mentioned one does):

[TestCase(null)]
[TestCase("")]
[TestCase("..@test.com")]
[TestCase(".a@test.com")]
[TestCase("ab@sd@dd")]
[TestCase(".@s.dd")]
[TestCase("ab@988.120.150.10")]
[TestCase("ab@120.256.256.120")]
[TestCase("ab@120.25.1111.120")]
[TestCase("ab@[188.120.150.10")]
[TestCase("ab@188.120.150.10]")]
[TestCase("ab@[188.120.150.10].com")]
[TestCase("a@b.-de.cc")]
[TestCase("a@bde-.cc")]
[TestCase("a@bde.c-c")]
[TestCase("a@bde.cc.")]
[TestCase("ab@b+de.cc")]
[TestCase("a..b@bde.cc")]
[TestCase("_@bde.cc,")]
[TestCase("plainaddress")]
[TestCase("plain.address")]
[TestCase("@%^%#$@#$@#.com")]
[TestCase("@domain.com")]
[TestCase("Joe Smith &lt;email@domain.com&gt;")]
[TestCase("email.domain.com")]
[TestCase("email@domain@domain.com")]
[TestCase(".email@domain.com")]
[TestCase("email.@domain.com")]
[TestCase("email..email@domain.com")]
[TestCase("email@-domain.com")]
[TestCase("email@domain-.com")]
[TestCase("email@domain.com-")]
[TestCase("email@.domain.com")]
[TestCase("email@domain.com.")]
[TestCase("email@domain..com")]
[TestCase("email@111.222.333")]
[TestCase("email@111.222.333.256")]
[TestCase("email@[123.123.123.123")]
[TestCase("email@[123.123.123].123")]
[TestCase("email@123.123.123.123]")]
[TestCase("email@123.123.[123.123]")]
[TestCase("email@{leftbracket.com")]
[TestCase("email@rightbracket}.com")]
[TestCase("email@p|pe.com")]
[TestCase("isis@100%.nl")]
[TestCase("email@dollar$.com")]
[TestCase("email@r&amp;d.com")]
[TestCase("email@#hash.com")]
[TestCase("email@wave~tilde.com")]
[TestCase("email@exclamation!mark.com")]
[TestCase("email@question?mark.com")]
[TestCase("email@obelix*asterisk.com")]
[TestCase("email@grave`accent.com")]
[TestCase("email@colon:colon.com")]
[TestCase("email@caret^xor.com")]
[TestCase("email@=qowaiv.com")]
[TestCase("email@plus+.com")]
[TestCase("email@domain.com>")]
[TestCase("email( (nested) )@plus.com")]
[TestCase("email)mirror(@plus.com")]
[TestCase("email@plus.com (not closed comment")]
[TestCase("email(with @ in comment)plus.com")]
[TestCase(@"""Joe Smith email@domain.com")]
[TestCase(@"""Joe Smith' email@domain.com")]
[TestCase(@"""Joe Smith""email@domain.com")]
[TestCase("email@mailto:domain.com")]
[TestCase("mailto:mailto:email@domain.com")]
[TestCase("Display Name <email@plus.com> (after name with display)")]
[TestCase("ReDoSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")]
public void IsInvalid(string email)
{
    Assert.IsFalse(EmailAddress.IsValid(email), email);
}

[TestCase("w@com")]
[TestCase("w.b.f@test.com")]
[TestCase("w.b.f@test.museum")]
[TestCase("a.a@test.com")]
[TestCase("ab@288.120.150.10.com")]
[TestCase("ab@188.120.150.10")]
[TestCase("ab@1.0.0.10")]
[TestCase("ab@120.25.254.120")]
[TestCase("ab@01.120.150.1")]
[TestCase("ab@88.120.150.021")]
[TestCase("ab@88.120.150.01")]
[TestCase("ab@[120.254.254.120]")]
[TestCase("local@2001:0db8:85a3:0000:0000:8a2e:0370:7334")]
[TestCase("local@[2001:0db8:85a3:0000:0000:8a2e:0370:7334]")]
[TestCase("2@bde.cc")]
[TestCase("-@bde.cc")]
[TestCase("a2@bde.cc")]
[TestCase("a-b@bde.cc")]
[TestCase("ab@b-de.cc")]
[TestCase("a+b@bde.cc")]
[TestCase("f.f.f@bde.cc")]
[TestCase("ab_c@bde.cc")]
[TestCase("_-_@bde.cc")]
[TestCase("k.haak@12move.nl")]
[TestCase("K.HAAK@12MOVE.NL")]
[TestCase("email@domain.com")]
[TestCase("email@domain")]
[TestCase("あいうえお@domain.com")]
[TestCase("local@あいうえお.com")]
[TestCase("firstname.lastname@domain.com")]
[TestCase("email@subdomain.domain.com")]
[TestCase("firstname+lastname@domain.com")]
[TestCase("email@123.123.123.123")]
[TestCase("email@[123.123.123.123]")]
[TestCase("1234567890@domain.com")]
[TestCase("a@domain.com")]
[TestCase("a.b.c.d@domain.com")]
[TestCase("aap.123.noot.mies@domain.com")]
[TestCase("1@domain.com")]
[TestCase("email@domain-one.com")]
[TestCase("_______@domain.com")]
[TestCase("email@domain.topleveldomain")]
[TestCase("email@domain.co.jp")]
[TestCase("firstname-lastname@domain.com")]
[TestCase("firstname-lastname@d.com")]
[TestCase("FIRSTNAME-LASTNAME@d--n.com")]
[TestCase("first-name-last-name@d-a-n.com")]
[TestCase("{local{name{{with{@leftbracket.com")]
[TestCase("}local}name}}with{@rightbracket.com")]
[TestCase("|local||name|with|@pipe.com")]
[TestCase("%local%%name%with%@percentage.com")]
[TestCase("$local$$name$with$@dollar.com")]
[TestCase("&local&&name&with&$@amp.com")]
[TestCase("#local##name#with#@hash.com")]
[TestCase("~local~~name~with~@tilde.com")]
[TestCase("!local!!name!with!@exclamation.com")]
[TestCase("?local??name?with?@question.com")]
[TestCase("*local**name*with*@asterisk.com")]
[TestCase("`local``name`with`@grave-accent.com")]
[TestCase("^local^^name^with^@xor.com")]
[TestCase("=local==name=with=@equality.com")]
[TestCase("+local++name+with+@equality.com")]
[TestCase("Joe Smith <email@domain.com>")]
[TestCase("email@domain.com (joe Smith)")]
[TestCase(@"""Joe Smith"" email@domain.com")]
[TestCase(@"""Joe\\tSmith"" email@domain.com")]
[TestCase(@"""Joe\""Smith"" email@domain.com")]
[TestCase(@"Test |<gaaf <email@domain.com>")]
[TestCase("MailTo:casesensitve@domain.com")]
[TestCase("mailto:email@domain.com")]
[TestCase("Joe Smith <mailto:email@domain.com>")]
[TestCase("Joe Smith <mailto:email(with comment)@domain.com>")]
[TestCase(@"""With extra < within quotes"" Display Name<email@domain.com>")]
[TestCase("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")]
public void IsValid(string email)
{
    Assert.IsTrue(EmailAddress.IsValid(email), email);
}
Corniel Nobel
  • 353
  • 3
  • 12
0

I wrote an function to check if an email is valid or not. It seems working well for me in most cases.

Results:

dasddas-@.com => FALSE
-asd@das.com => FALSE
as3d@dac.coas- => FALSE
dsq!a?@das.com => FALSE
_dasd@sd.com => FALSE
dad@sds => FALSE
asd-@asd.com => FALSE
dasd_-@jdas.com => FALSE
asd@dasd@asd.cm => FALSE
da23@das..com => FALSE
_dasd_das_@9.com => FALSE

d23d@da9.co9 => TRUE
dasd.dadas@dasd.com => TRUE
dda_das@das-dasd.com => TRUE
dasd-dasd@das.com.das => TRUE

Code:

    private bool IsValidEmail(string email)
    {
        bool valid = false;
        try
        {
            var addr = new System.Net.Mail.MailAddress(email);
            valid = true;
        }
        catch
        {
            valid = false;
            goto End_Func;
        }

        valid = false;
        int pos_at = email.IndexOf('@');
        char checker = Convert.ToChar(email.Substring(pos_at + 1, 1));
        var chars = "qwertyuiopasdfghjklzxcvbnm0123456789";
        foreach (char chr in chars)
        {
            if (checker == chr)
            {
                valid = true;
                break;
            }
        }
        if (valid == false)
        {
            goto End_Func;
        } 

        int pos_dot = email.IndexOf('.', pos_at + 1);
        if(pos_dot == -1)
        {
            valid = false;
            goto End_Func;
        }

        valid = false;
        try
        {
            checker = Convert.ToChar(email.Substring(pos_dot + 1, 1));
            foreach (char chr in chars)
            {
                if (checker == chr)
                {
                    valid = true;
                    break;
                }
            }
        }
        catch
        {
            valid = false;
            goto End_Func;
        }

        Regex valid_checker = new Regex(@"^[a-zA-Z0-9_@.-]*$");
        valid = valid_checker.IsMatch(email);
        if (valid == false)
        {
            goto End_Func;
        }

        List<int> pos_list = new List<int> { };
        int pos = 0;
        while (email.IndexOf('_', pos) != -1)
        {
            pos_list.Add(email.IndexOf('_', pos));
            pos = email.IndexOf('_', pos) + 1;
        }

        pos = 0;
        while (email.IndexOf('.', pos) != -1)
        {
            pos_list.Add(email.IndexOf('.', pos));
            pos = email.IndexOf('.', pos) + 1;
        }

        pos = 0;
        while (email.IndexOf('-', pos) != -1)
        {
            pos_list.Add(email.IndexOf('-', pos));
            pos = email.IndexOf('-', pos) + 1;
        }

        int sp_cnt = pos_list.Count();
        pos_list.Sort();
        for (int i = 0; i < sp_cnt - 1; i++)
        {
            if (pos_list[i] + 1 == pos_list[i + 1])
            {
                valid = false;
                break;
            }

            if (pos_list[i]+1 == pos_at || pos_list[i]+1 == pos_dot)
            {
                valid = false;
                break;
            }
        }

        if(valid == false)
        {
            goto End_Func;
        }

        if (pos_list[sp_cnt - 1] == email.Length - 1 || pos_list[0] == 0)
        {
            valid = false;
        }

    End_Func:;
        return valid;
    }
Louis Tran
  • 1,078
  • 16
  • 37
0

What if you combine multiple solutions to make a perfect code?

i got top 2 Solutions having highest Ranks and Reviews and combined them to get more accurate Answers. its Short, fast and adorable.

    public static bool isValidEmail(string email)
    {
        try
        {
            var addr = new System.Net.Mail.MailAddress(email);
            if (addr.Address == email)
            {
                string expression = "\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*"; 
                if (Regex.IsMatch(email, expression))
                {
                    if (Regex.Replace(email, expression, string.Empty).Length == 0) 
                        return true; 
                }
                return false;
            }
            return false; 
        }
        catch
        {
            return false;
        }  
    }
0

I use this one to validate emails often and it works like a charm. This validates that the email must have atleast one character before the @, and at least one character before the "."

public static bool ValidateEmail(string value, bool required, int minLength, int maxLength)
        {
           value = value.Trim();
           if (required == false && value == "") return true;
           if (required && value == "") return false;
           if (value.Length < minLength || value.Length > maxLength) return false;

           //Email must have at least one character before an @, and at least one character before the .
           int index = value.IndexOf('@');
           if (index < 1 || value.LastIndexOf('.') < index + 2) return false;
           return true;
        }
Andrew Reese
  • 710
  • 6
  • 23
0

I summarize all the above answers as of the current year 2021 I wrote for myself this class:

public static class StringExt {
    private const string emailPattern = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|" 
            + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)" 
            + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";

    public static bool IsValidMailAddress(this string pThis) 
            => pThis is not null 
            && Regex.IsMatch(pThis, emailPattern, RegexOptions.IgnoreCase);
}
Vasya Milovidov
  • 337
  • 5
  • 18
-1
  1. In a "try block" send a verification email.
  2. Make the user open the email and click a link verifying the email is real.

Until this process completes successfully, the email is assumed to be invalid.

Timothy Shields
  • 65,578
  • 17
  • 107
  • 158
-1

Some time back, I wrote an EmailAddressValidationAttribute that should properly validate pretty much any relatively normal email address of the form

local-part@domain

It's a System.ComponentModel.DataAnnotations.ValidationAttribute, so usage is really simple.

And, since digging through all the RFCs and errata and assembling all the bits required to properly enumerate all the rules is...tedious — at best! — I posted the source code for the validator in my answer to the question C# Email Address validation for the source code.

My validator isn't perfect by any stretch of the imagination, though Just for starters, it doesn't have any built-in support for emitting client-side javascript validation, though it wouldn't be too difficult to add that in. From my answer above:

Here's the validation attribute I wrote. It validates pretty much every "raw" email address, that is those of the form local-part@domain. It doesn't support any of the other, more...creative constructs that the RFCs allow (this list is not comprehensive by any means):

  • comments (e.g., jsmith@whizbang.com (work))
  • quoted strings (escaped text, to allow characters not allowed in an atom)
  • domain literals (e.g. foo@[123.45.67.012])
  • bang-paths (aka source routing)
  • angle addresses (e.g. John Smith <jsmith@whizbang.com>)
  • folding whitespace
  • double-byte characters in either local-part or domain (7-bit ASCII only).
  • etc.

It should accept almost any email address that can be expressed thusly

  • foo.bar@bazbat.com

without requiring the use of quotes ("), angle brackets ('<>') or square brackets ([]).

No attempt is made to validate that the rightmost dns label in the domain is a valid TLD (top-level domain). That is because the list of TLDs is far larger now than the "big 6" (.com, .edu, .gov, .mil, .net, .org) plus 2-letter ISO country codes. ICANN actually updates the TLD list daily, though I suspect that the list doesn't actually change daily. Further, [ICANN just approved a big expansion of the generic TLD namespace][2]). And some email addresses don't have what you'd recognize as a TLD (did you know that postmaster@. is theoretically valid and mailable? Mail to that address should get delivered to the postmaster of the DNS root zone.)

Extending the regular expression to support domain literals shouldn't be too difficult.

Community
  • 1
  • 1
Nicholas Carey
  • 60,260
  • 12
  • 84
  • 126
-1

I created an email address validation routine based on Wikipedia's documented rules and sample addresses. For those that don't mind looking at a little more code, here you go. Honestly, I had no idea how many crazy rules there were in the email address specification. I don't fully validate the hostname or ipaddress, but it still passes all of the test cases on wikipedia.

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace EmailValidateUnitTests
{
    [TestClass]
    public class EmailValidationUnitTests
    {
        [TestMethod]
        public void TestEmailValidate()
        {
            // Positive Assertions
            Assert.IsTrue("prettyandsimple@example.com".IsValidEmailAddress());
            Assert.IsTrue("very.common@example.com".IsValidEmailAddress());
            Assert.IsTrue("disposable.style.email.with+symbol@example.com".IsValidEmailAddress());
            Assert.IsTrue("other.email-with-dash@example.com".IsValidEmailAddress());
            Assert.IsTrue("\"much.more unusual\"@example.com".IsValidEmailAddress());
            Assert.IsTrue("\"very.unusual.@.unusual.com\"@example.com".IsValidEmailAddress()); //"very.unusual.@.unusual.com"@example.com
            Assert.IsTrue("\"very.(),:;<>[]\\\".VERY.\\\"very@\\\\ \\\"very\\\".unusual\"@strange.example.com".IsValidEmailAddress()); //"very.(),:;<>[]\".VERY.\"very@\\ \"very\".unusual"@strange.example.com
            Assert.IsTrue("admin@mailserver1".IsValidEmailAddress());
            Assert.IsTrue("#!$%&'*+-/=?^_`{}|~@example.org".IsValidEmailAddress());
            Assert.IsTrue("\"()<>[]:,;@\\\\\\\"!#$%&'*+-/=?^_`{}| ~.a\"@example.org".IsValidEmailAddress()); //"()<>[]:,;@\\\"!#$%&'*+-/=?^_`{}| ~.a"@example.org
            Assert.IsTrue("\" \"@example.org".IsValidEmailAddress()); //" "@example.org (space between the quotes)
            Assert.IsTrue("example@localhost".IsValidEmailAddress());
            Assert.IsTrue("example@s.solutions".IsValidEmailAddress());
            Assert.IsTrue("user@com".IsValidEmailAddress());
            Assert.IsTrue("user@localserver".IsValidEmailAddress());
            Assert.IsTrue("user@[IPv6:2001:db8::1]".IsValidEmailAddress());
            Assert.IsTrue("user@[192.168.2.1]".IsValidEmailAddress());
            Assert.IsTrue("(comment and stuff)joe@gmail.com".IsValidEmailAddress());
            Assert.IsTrue("joe(comment and stuff)@gmail.com".IsValidEmailAddress());
            Assert.IsTrue("joe@(comment and stuff)gmail.com".IsValidEmailAddress());
            Assert.IsTrue("joe@gmail.com(comment and stuff)".IsValidEmailAddress());

            // Failure Assertions
            Assert.IsFalse("joe(fail me)smith@gmail.com".IsValidEmailAddress());
            Assert.IsFalse("joesmith@gma(fail me)il.com".IsValidEmailAddress());
            Assert.IsFalse("joe@gmail.com(comment and stuff".IsValidEmailAddress());
            Assert.IsFalse("Abc.example.com".IsValidEmailAddress());
            Assert.IsFalse("A@b@c@example.com".IsValidEmailAddress());
            Assert.IsFalse("a\"b(c)d,e:f;g<h>i[j\\k]l@example.com".IsValidEmailAddress()); //a"b(c)d,e:f;g<h>i[j\k]l@example.com
            Assert.IsFalse("just\"not\"right@example.com".IsValidEmailAddress()); //just"not"right@example.com
            Assert.IsFalse("this is\"not\\allowed@example.com".IsValidEmailAddress()); //this is"not\allowed@example.com
            Assert.IsFalse("this\\ still\\\"not\\\\allowed@example.com".IsValidEmailAddress());//this\ still\"not\\allowed@example.com
            Assert.IsFalse("john..doe@example.com".IsValidEmailAddress());
            Assert.IsFalse("john.doe@example..com".IsValidEmailAddress());
            Assert.IsFalse(" joe@gmail.com".IsValidEmailAddress());
            Assert.IsFalse("joe@gmail.com ".IsValidEmailAddress());
        }
    }

    public static class ExtensionMethods
    {
        private const string ValidLocalPartChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&'*+-/=?^_`{|}~";
        private const string ValidQuotedLocalPartChars = "(),:;<>@[]. ";
        private const string ValidDomainPartChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-:";

        private enum EmailParseMode
        {
            BeginLocal, Local, QuotedLocalEscape, QuotedLocal, QuotedLocalEnd, LocalSplit, LocalComment,
            At,
            Domain, DomainSplit, DomainComment, BracketedDomain, BracketedDomainEnd
        };

        public static bool IsValidEmailAddress(this string s)
        {
            bool valid = true;

            bool hasLocal = false, hasDomain = false;
            int commentStart = -1, commentEnd = -1;
            var mode = EmailParseMode.BeginLocal;
            for (int i = 0; i < s.Length; i++)
            {
                char c = s[i];
                if (mode == EmailParseMode.BeginLocal || mode == EmailParseMode.LocalSplit)
                {
                    if (c == '(') { mode = EmailParseMode.LocalComment; commentStart = i; commentEnd = -1; }
                    else if (c == '"') { mode = EmailParseMode.QuotedLocal; }
                    else if (ValidLocalPartChars.IndexOf(c) >= 0) { mode = EmailParseMode.Local; hasLocal = true; }
                    else { valid = false; break; }
                }
                else if (mode == EmailParseMode.LocalComment)
                {
                    if (c == ')')
                    {
                        mode = EmailParseMode.Local; commentEnd = i;
                        // comments can only be at beginning and end of parts...
                        if (commentStart != 0 && ((commentEnd + 1) < s.Length) && s[commentEnd + 1] != '@') { valid = false; break; }
                    }
                }
                else if (mode == EmailParseMode.Local)
                {
                    if (c == '.') mode = EmailParseMode.LocalSplit;
                    else if (c == '@') mode = EmailParseMode.At;
                    else if (c == '(') { mode = EmailParseMode.LocalComment; commentStart = i; commentEnd = -1; }
                    else if (ValidLocalPartChars.IndexOf(c) >= 0) { hasLocal = true; }
                    else { valid = false; break; }
                }
                else if (mode == EmailParseMode.QuotedLocal)
                {
                    if (c == '"') { mode = EmailParseMode.QuotedLocalEnd; }
                    else if (c == '\\') { mode = EmailParseMode.QuotedLocalEscape; }
                    else if (ValidLocalPartChars.IndexOf(c) >= 0 || ValidQuotedLocalPartChars.IndexOf(c) >= 0) { hasLocal = true; }
                    else { valid = false; break; }
                }
                else if (mode == EmailParseMode.QuotedLocalEscape)
                {
                    if (c == '"' || c == '\\') { mode = EmailParseMode.QuotedLocal; hasLocal = true; }
                    else { valid = false; break; }
                }
                else if (mode == EmailParseMode.QuotedLocalEnd)
                {
                    if (c == '.') { mode = EmailParseMode.LocalSplit; }
                    else if (c == '@') mode = EmailParseMode.At;
                    else if (c == '(') { mode = EmailParseMode.LocalComment; commentStart = i; commentEnd = -1; }
                    else { valid = false; break; }
                }
                else if (mode == EmailParseMode.At)
                {
                    if (c == '[') { mode = EmailParseMode.BracketedDomain; }
                    else if (c == '(') { mode = EmailParseMode.DomainComment; commentStart = i; commentEnd = -1; }
                    else if (ValidDomainPartChars.IndexOf(c) >= 0) { mode = EmailParseMode.Domain; hasDomain = true; }
                    else { valid = false; break; }
                }
                else if (mode == EmailParseMode.DomainComment)
                {
                    if (c == ')')
                    {
                        mode = EmailParseMode.Domain;
                        commentEnd = i;
                        // comments can only be at beginning and end of parts...
                        if ((commentEnd + 1) != s.Length && (commentStart > 0) && s[commentStart - 1] != '@') { valid = false; break; }
                    }
                }
                else if (mode == EmailParseMode.DomainSplit)
                {
                    if (ValidDomainPartChars.IndexOf(c) >= 0) { mode = EmailParseMode.Domain; hasDomain = true; }
                    else { valid = false; break; }
                }
                else if (mode == EmailParseMode.Domain)
                {
                    if (c == '(') { mode = EmailParseMode.DomainComment; commentStart = i; commentEnd = -1; }
                    else if (c == '.') { mode = EmailParseMode.DomainSplit; }
                    else if (ValidDomainPartChars.IndexOf(c) >= 0) { hasDomain = true; }
                    else { valid = false; break; }
                }
                else if (mode == EmailParseMode.BracketedDomain)
                {
                    if (c == ']') { mode = EmailParseMode.BracketedDomainEnd; }
                    else if (c == '.' || ValidDomainPartChars.IndexOf(c) >= 0) { hasDomain = true; }
                    else { valid = false; break; }
                }
                else if (mode == EmailParseMode.BracketedDomain)
                {
                    if (c == '(') { mode = EmailParseMode.DomainComment; commentStart = i; commentEnd = -1; }
                    else { valid = false; break; }
                }
            }
            bool unfinishedComment = (commentEnd == -1 && commentStart >= 0);

            return hasLocal && hasDomain && valid && !unfinishedComment;
        }
    }
}
komma8.komma1
  • 1,190
  • 2
  • 12
  • 20
-2
    /// <summary>
    /// Validates the email if it follows the valid email format
    /// </summary>
    /// <param name="emailAddress"></param>
    /// <returns></returns>
    public static bool EmailIsValid(string emailAddress)
    {
        //if string is not null and empty then check for email follow the format
        return string.IsNullOrEmpty(emailAddress)?false : new Regex(@"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$", RegexOptions.IgnoreCase).IsMatch(emailAddress);
    }
faisal
  • 99
  • 1
  • 4
-2

This may be the best way for the email validation for your textbox.

string pattern = null;
pattern = "^([0-9a-zA-Z]([-\\.\\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\\w]*[0-9a-zA-Z]\\.)+[a-zA-Z]{2,9})$";

if (Regex.IsMatch("txtemail.Text", pattern))
{
MessageBox.Show ("Valid Email address ");
}
else
{
MessageBox.Show("Invalid Email Email");
}

Just include in any function where you want.

-3
public static bool IsEmail(string strEmail)
{
    Regex rgxEmail = new Regex(@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" +
                               @"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" +
                               @".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
    return rgxEmail.IsMatch(strEmail);
}
jesal
  • 7,044
  • 5
  • 47
  • 51
-5
   public bool IsValidEmail(string email)
    {
        try
        {
            var addr = new System.Net.Mail.MailAddress(email);
            return addr.Address == email;
        }
        catch
        {
            return false;
        }
    }
Ronel Gonzales
  • 125
  • 1
  • 6
  • the method name is not using proper conventions. The method body could be clearer –  Sep 19 '19 at 10:48