It's very, very hard and complicated to write a regular expression that will conform exactly to mail address RFC standards - and also, keep in mind the standards keeps updating.
Microsoft's official recommendation used to be to use a long, unreadable, unmaintainable regular expression - however they did change that recommendation to use a simple, short regular expression that will only validate that there's a @
and a .
separated by at least one non-space char between them and between the start and end of the string - so an email address like a@b.c
can pass this test.
If you're working with large amounts of strings and fear a performance penalty, go ahead and verity that the string will likely pass the EmailAddress
constructor using the regular expression suggested in the docs, which is simple enough to read and understand - ^[^@\s]+@[^@\s]+\.[^@\s]+$
(note that a@b
is still a valid mail address....)
Then, simply attempt to create an instance of MailAddress
in a try...catch
block.
This will also help you parse the mail address, because this class has properties that does a lot of the work for you - you can get the Host, the User, and even the Display name (if provided, of course).
Here's a simple demo (check it live on Rextester):
public static void Main(string[] args)
{
var strings = new [] {
"user<test@nomail.com>", // valid.
"test@nomail.com", // valid.
"Invalid<testnomail.com>", // Invalid.
"Invalid<test@com>", // Invalid. Note: This will return a "false positive" if only tested using MailAddress's constructor - but it's not really false.
};
foreach(var a in strings)
{
ParseMailAddress(a);
}
}
static void ParseMailAddress(string address)
{
Console.WriteLine("--------------------------------------------");
Console.WriteLine("Input: {0}", address);
if(! Regex.IsMatch(address, @"^[^@\s]+@[^@\s]+\.[^@\s]+$") )
{
Console.WriteLine("Failed regex validation");
return;
}
try
{
var mailAddress = new MailAddress(address);
Console.WriteLine("Address: {0}", mailAddress.Address);
Console.WriteLine("DisplayName: {0}", mailAddress.DisplayName);
Console.WriteLine("Host: {0}", mailAddress.Host);
Console.WriteLine("User: {0}", mailAddress.User);
}
catch (FormatException ex)
{
Console.WriteLine("Error: {0}", ex);
}
}
And the results:
--------------------------------------------
Input: user<test@nomail.com>
Address: test@nomail.com
DisplayName: user
Host: nomail.com
User: test
--------------------------------------------
Input: test@nomail.com
Address: test@nomail.com
DisplayName:
Host: nomail.com
User: test
--------------------------------------------
Input: Invalid<testnomail.com>
Failed regex validation
--------------------------------------------
Input: Invalid<test@com>
Failed regex validation