0

I'm trying to parse email address to display name, address.
This is the example. user<test@nomail.com> => user, test@nomail.com

I've implemented this using MailAddress class,
But my problem is that if string is not valid email address, MailAddress throws an exception - and I do not want the exception.

I've searched many email validation method using regex but they check email only (test@nomail.com) but not the full address (user<test@nomail.com>).

How can I solve this problem?

Zohar Peled
  • 79,642
  • 10
  • 69
  • 121
Jack Lee
  • 363
  • 5
  • 18
  • Why not use try-catch with MailAddress class? – shingo Nov 02 '20 at 06:21
  • 1
    Does this answer your question? [How to validate an email address using a regular expression?](https://stackoverflow.com/questions/201323/how-to-validate-an-email-address-using-a-regular-expression) – Klaus Gütter Nov 02 '20 at 06:23
  • I used try-catch, but there are a lot of non email data and it causes too many exception and performance problem. So i want to check before try, catch. – Jack Lee Nov 02 '20 at 06:28
  • 1
    I've actually blogged about mail validation - [Validate mail address format the easy way – a follow up](https://zoharpeled.wordpress.com/2020/04/06/validate-mail-address-format-the-easy-way-a-follow-up/) – Zohar Peled Nov 02 '20 at 06:31

1 Answers1

2

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
Zohar Peled
  • 79,642
  • 10
  • 69
  • 121