Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Email Validation: converting a regular expression written in PHP (preg) to .NET (Regex)

Based on this answer... Using a regular expression to validate an email address

Which led me to this site... http://fightingforalostcause.net/misc/2006/compare-email-regex.php

I'd like to use this regex for email validation for my ASP.NET MVC app:

/^[-_a-z0-9\'+*$^&%=~!?{}]++(?:\.[-_a-z0-9\'+*$^&%=~!?{}]+)*+@(?:(?![-.])[-a-z0-9.]+(?<![-.])\.[a-z]{2,6}|\d{1,3}(?:\.\d{1,3}){3})(?::\d++)?$/iD

Unfortunately, I get this error

System.ArgumentException was unhandled by user code Message="parsing \"/^[-_a-z0-9\'+$^&%=~!?{}]++(?:\.[-_a-z0-9\'+$^&%=~!?{}]+)*+@(?:(?![-.])[-a-z0-9.]+(?

Has anyone ever converted this to be usable by .NET's Regex class, or is there another .NET regular expression class that is a better fit with PHP's preg_match function?

like image 664
devuxer Avatar asked Dec 30 '22 06:12

devuxer


2 Answers

The problem with your regular expression in .NET is that the possessive quantifiers aren't supported. If you remove those, it works. Here's the regular expression as a C# string:

@"^[-_a-z0-9\'+*$^&%=~!?{}]+(?:\.[-_a-z0-9\'+*$^&%=~!?{}]+)*@(?:(?![-.])[-a-z0-9.]+(?<![-.])\.[a-z]{2,6}|\d{1,3}(?:\.\d{1,3}){3})(?::\d+)?$"

Here's a test bed for it based on the page you linked to, including all the strings that should match and the first three of those that shouldn't:

using System;
using System.Text.RegularExpressions;

public class Program
{
    static void Main(string[] args)
    {
        foreach (string email in new string[]{
            "[email protected]",
            "[email protected]",
            "hasApostrophe.o'[email protected]",
            "[email protected]",
            "[email protected]",
            "[email protected]",
            "[email protected]",
            "[email protected]",
            "[email protected]",
            "[email protected]",
            "[email protected]",
            "[email protected]:25",
            "[email protected]",
            "[email protected]",
            "[email protected]",
            "[email protected]",
            "[email protected]",
            "&*=?^+{}'[email protected]",
            "[email protected]",
            "@missingLocal.org",
            "missingatSign.net"
        })
        {
            string s = @"^[-_a-z0-9\'+*$^&%=~!?{}]+(?:\.[-_a-z0-9\'+*$^&%=~!?{}]+)*@(?:(?![-.])[-a-z0-9.]+(?<![-.])\.[a-z]{2,6}|\d{1,3}(?:\.\d{1,3}){3})(?::\d+)?$";
            bool isMatch = Regex.IsMatch(email, s, RegexOptions.IgnoreCase);
            Console.WriteLine(isMatch);
        }
    }
}

Output:

True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
False
False
False

A problem though is that it fails to match some valid email-addresses, such as foo\@[email protected]. It's better too match too much than too little.

like image 128
Mark Byers Avatar answered Dec 31 '22 20:12

Mark Byers


You really shouldn't be using a RegEx to parse email addresses in .NET. Your better option is to use the functionality built into the framework.

Try to use your email string in the constructor of the MailAddress class. If it throws a FormatException then the address is no good.

try 
{
    MailAddress addr = new MailAddress("[email protected]")
    // <- Valid email if this line is reached
}
catch (FormatException)
{
    // <- Invalid email if this line is reached
}

You can see an answer a Microsoft developer gave to another email validation question, where he explains how .NET's email parsing has also improved dramatically in .NET 4.0. Since at the time of answering this, .NET 4.0 is still in beta, you probably aren't running it, however even previous versions of the framework have adequate email address parsing code. Remember, in the end you're most likely going to be using the MailAddress class to send your email anyway. Why not use it to validation your email addresses. In the end, being valid to the MailAddress class is all that matters anyway.

like image 29
Dan Herbert Avatar answered Dec 31 '22 20:12

Dan Herbert