How to: Verify That Strings Are in Valid E-Mail Format
The following example verifies that a string is in valid e-email format.
Example
The example defines an IsValidEmail method, which returns true if the string contains a valid email address and false if it does not, but takes no other action.
To verify that the email address is valid, the IsValidEmail method calls the Regex.Replace(String, String, MatchEvaluator) method with the (@)(.)$ regular expression pattern to separate the domain name from the email address. The third parameter is a MatchEvaluator delegate that represents the method that processes and replaces the matched text. The regular expression pattern is interpreted as follows.
Pattern |
Description |
---|---|
(@) |
Match the @ character. This is the first capturing group. |
(.) |
Match one or more occurrences of any character. This is the second capturing group. |
$ |
End the match at the end of the string. |
The domain name along with the @ character is passed to the DomainMapper method, which uses the IdnMapping class to translate Unicode characters that are outside the US-ASCII character range to Punycode. The method also sets the invalid flag to True if the IdnMapping.GetAscii method detects any invalid characters in the domain name. The method returns the Punycode domain name preceded by the @ symbol to the IsValidEmail method.
The IsValidEmail method then calls the Regex.IsMatch(String, String) method to verify that the address conforms to a regular expression pattern.
Note that the IsValidEmail method does not perform authentication to validate the email address. It merely determines whether its format is valid for an email address.
Imports System.Globalization
Imports System.Text.RegularExpressions
Public Class RegexUtilities
Dim invalid As Boolean = False
public Function IsValidEmail(strIn As String) As Boolean
invalid = False
If String.IsNullOrEmpty(strIn) Then Return False
' Use IdnMapping class to convert Unicode domain names.
strIn = Regex.Replace(strIn, "(@)(.)$", AddressOf Me.DomainMapper)
If invalid Then Return False
' Return true if strIn is in valid e-mail format.
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]{2,17}))$",
RegexOptions.IgnoreCase)
End Function
Private Function DomainMapper(match As Match) As String
' IdnMapping class with default property values.
Dim idn As New IdnMapping()
Dim domainName As String = match.Groups(2).Value
Try
domainName = idn.GetAscii(domainName)
Catch e As ArgumentException
invalid = True
End Try
Return match.Groups(1).Value + domainName
End Function
End Class
using System;
using System.Globalization;
using System.Text.RegularExpressions;
public class RegexUtilities
{
bool invalid = false;
public bool IsValidEmail(string strIn)
{
invalid = false;
if (String.IsNullOrEmpty(strIn))
return false;
// Use IdnMapping class to convert Unicode domain names.
strIn = Regex.Replace(strIn, @"(@)(.)$", this.DomainMapper);
if (invalid)
return false;
// Return true if strIn is in valid e-mail format.
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]{2,17}))$",
RegexOptions.IgnoreCase);
}
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;
}
}
In this example, the regular expression pattern ^(?("")(""[^""]+?""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9]{2,17}))$ is interpreted as shown in the following table. Note that the regular expression is compiled using the RegexOptions.IgnoreCase flag.
Pattern |
Description |
---|---|
^ |
Begin the match at the start of the string. |
(?("") |
Determine whether the first character is a quotation mark. (?("") is the beginning of an alternation construct. |
((?("")(""[^""]+?""@) |
If the first character is a quotation mark, match a beginning quotation mark followed by at least one occurrence of any character other than a quotation mark, followed by an ending quotation mark. The string should conclude with an at sign (@). |
|(([0-9a-zA-Z] |
If the first character is not a quotation mark, match any alphabetic character from a to z or any numeric character from 0 to 9. |
(\.(?!\.)) |
If the next character is a period, match it. If it is not a period, look ahead to the next character and continue the match. (?!\.) is a zero-width negative lookahead assertion that prevents two consecutive periods from appearing in the local part of an email address. |
|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w] |
If the next character is not a period, match any word character or one of the following characters: -!#$%'*+=?^`{}|~. |
((\.(?!\.))|[-!#\$%'\*\+/=\?\^`\{\}\|~\w])* |
Match the alternation pattern (a period followed by a non-period, or one of a number of characters) zero or more times. |
@ |
Match the @ character. |
(?<=[0-9a-z]) |
Continue the match if the character that precedes the @ character is A through Z, a through z, or 0 through 9. The (?<=[0-9a-z]) construct defines a zero-width positive lookbehind assertion. |
(?(\[) |
Check whether the character that follows @ is an opening bracket. |
(\[(\d{1,3}\.){3}\d{1,3}\]) |
If it is an opening bracket, match the opening bracket followed by an IP address (four sets of one to three digits, with each set separated by a period) and a closing bracket. |
|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9]{2,17}) |
If the character that follows @ is not an opening bracket, match one alphanumeric character with a value of A-Z, a-z, or 0-9, followed by zero or more occurrences of a word character or a hyphen, followed by zero or one alphanumeric character with a value of A-Z, a-z, or 0-9, followed by a period. This pattern can be repeated one or more times, and should be followed by two to seventeen alphabetic (a-z, A-Z) characters. This portion of the regular expression is designed to capture the domain name. |
$ |
End the match at the end of the string. |
Compiling the Code
The IsValidEmail method can be included in a library of regular expression utility methods, or it could be included as a private static or instance method in the application class. If it is used as a static method in a regular expression library, it can be called by using code such as the following:
Public Class Application
Public Shared Sub Main()
Dim util As New RegexUtilities()
Dim emailAddresses() As String = { "david.jones@proseware.com", "d.j@server1.proseware.com", _
"jones@ms1.proseware.com", "j.@server1.proseware.com", _
"j@proseware.com9", "js#internal@proseware.com", _
"j_9@[129.126.118.1]", "j..s@proseware.com", _
"js*@proseware.com", "js@proseware..com", _
"js@proseware.com9", "js@proseware.com9", "j.s@server1.proseware.com" }
For Each emailAddress As String In emailAddresses
If util.IsValidEmail(emailAddress) Then
Console.WriteLine("Valid: {0}", emailAddress)
Else
Console.WriteLine("Invalid: {0}", emailAddress)
End If
Next
End Sub
End Class
' The example displays the following output:
' Valid: david.jones@proseware.com
' Valid: d.j@server1.proseware.com
' Valid: jones@ms1.proseware.com
' Invalid: j.@server1.proseware.com
' Invalid: 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
' Invalid: js@proseware.com9
' Valid: j.s@server1.proseware.com
public class Application
{
public static void Main()
{
RegexUtilities util = new RegexUtilities();
string[] emailAddresses = { "david.jones@proseware.com", "d.j@server1.proseware.com",
"jones@ms1.proseware.com", "j.@server1.proseware.com",
"j@proseware.com9", "js#internal@proseware.com",
"j_9@[129.126.118.1]", "j..s@proseware.com",
"js*@proseware.com", "js@proseware..com",
"js@proseware.com9", "js@proseware.com9", "j.s@server1.proseware.com" };
foreach (var emailAddress in emailAddresses) {
if (util.IsValidEmail(emailAddress))
Console.WriteLine("Valid: {0}", emailAddress);
else
Console.WriteLine("Invalid: {0}", emailAddress);
}
}
}
// The example displays the following output:
// Valid: david.jones@proseware.com
// Valid: d.j@server1.proseware.com
// Valid: jones@ms1.proseware.com
// Invalid: j.@server1.proseware.com
// Invalid: 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
// Invalid: js@proseware.com9
// Valid: j.s@server1.proseware.com
See Also
Other Resources
.NET Framework Regular Expressions
Change History
Date |
History |
Reason |
---|---|---|
March 2012 |
Added IDNA support. |
Customer feedback. |
September 2011 |
Revised the regular expression to handle consecutive quotation marks. |
Customer feedback. |
January 2010 |
Revised the regular expression to validate additional e-mail addresses. |
Customer feedback. |
July 2009 |
Revised extensively. |
Customer feedback. |