如何确认字符串是有效的电子邮件格式

本文中的示例使用正则表达式来验证一个字符串是否为有效的电子邮件格式。

此正则表达式相对比实际上可用作电子邮件的表达式简单。 使用正则表达式来验证电子邮件是否有助于确保电子邮件的结构正确。 但这不是验证电子邮件是否实际存在的替代方法。

✔️ 请使用小型正则表达式来检查电子邮件的有效结构。

✔️ 请将测试电子邮件发送到应用用户提供的地址。

❌ 请勿将正则表达式用作验证电子邮件的唯一方法。

如果尝试创建完美的正则表达式来验证电子邮件的结构是否正确,表达式会变得非常复杂,以至于很难进行调试或改进。 即使电子邮件的结构正确,正则表达式也无法验证其是否存在。 验证电子邮件的最佳方法是将测试电子邮件发送到该地址。

警告

如果使用 System.Text.RegularExpressions 处理不受信任的输入,则传递一个超时。 恶意用户可能会向 RegularExpressions 提供输入,从而导致拒绝服务攻击。 使用 RegularExpressions 的 ASP.NET Core 框架 API 会传递一个超时。

示例

该示例定义 IsValidEmail 方法,如果字符串包含有效的电子邮件地址,则该方法返回 true;如果字符串不包含有效的电子邮件地址,但没有采取其他任何操作,该方法返回 false

若要验证电子邮件地址是否有效,方法 IsValidEmail 将使用 Regex.Replace(String, String, MatchEvaluator) 正则表达式模式调用 (@)(.+)$ 方法将域名从电子邮件地址分离。 第三个参数是表示了处理和替换匹配文本的方法的 MatchEvaluator 委托。 正则表达式模式的解释如下:

模式 描述
(@) 匹配 @ 字符。 此部分是第一个捕获组。
(.+) 匹配任意字符的一个或多个匹配项。 此部分是第二个捕获组。
$ 在字符串的结尾结束匹配。

使用 @ 字符的域名已传递给 DomainMapper 方法。 该方法使用 IdnMapping 类将 US-ASCII 字符范围外的 Unicode 字符转换为 Punycode。 如果 invalid 方法在域名中检测到任何无效字符,该方法还会将 True 标志设置为 IdnMapping.GetAscii 。 该方法将冠以 @ 符号的 Punycode 域名返回给 IsValidEmail 方法。

提示

建议使用简单的 (@)(.+)$ 正则表达式模式对域进行规范化,然后返回一个值,指示该域是通过还是失败。 但本文中的示例介绍如何使用正则表达式来进一步验证电子邮件。 无论验证电子邮件的方式如何,你都应始终将测试电子邮件发送到该地址,以确保其存在。

然后 IsValidEmail 方法调用 Regex.IsMatch(String, String) 方法验证该地址是否符合正则表达式模式。

IsValidEmail 方法只能确定电子邮件地址的格式是否有效;而不能验证电子邮件是否存在。 同样,IsValidEmail 方法不会验证顶级域名是否是 IANA 根区域数据库列出的有效域名,这需执行查找操作。

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

namespace RegexExamples
{
    class RegexUtilities
    {
        public static bool IsValidEmail(string email)
        {
            if (string.IsNullOrWhiteSpace(email))
                return false;

            try
            {
                // Normalize the domain
                email = Regex.Replace(email, @"(@)(.+)$", DomainMapper,
                                      RegexOptions.None, TimeSpan.FromMilliseconds(200));

                // Examines the domain part of the email and normalizes it.
                string DomainMapper(Match match)
                {
                    // Use IdnMapping class to convert Unicode domain names.
                    var idn = new IdnMapping();

                    // Pull out and process domain name (throws ArgumentException on invalid)
                    string domainName = idn.GetAscii(match.Groups[2].Value);

                    return match.Groups[1].Value + domainName;
                }
            }
            catch (RegexMatchTimeoutException e)
            {
                return false;
            }
            catch (ArgumentException e)
            {
                return false;
            }

            try
            {
                return Regex.IsMatch(email,
                    @"^[^@\s]+@[^@\s]+\.[^@\s]+$",
                    RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250));
            }
            catch (RegexMatchTimeoutException)
            {
                return false;
            }
        }
    }
}
Imports System.Globalization
Imports System.Text.RegularExpressions

Public Class RegexUtilities
    Public Shared Function IsValidEmail(email As String) As Boolean

        If String.IsNullOrWhiteSpace(email) Then Return False

        ' Use IdnMapping class to convert Unicode domain names.
        Try
            'Examines the domain part of the email and normalizes it.
            Dim DomainMapper =
                Function(match As Match) As String

                    'Use IdnMapping class to convert Unicode domain names.
                    Dim idn = New IdnMapping

                    'Pull out and process domain name (throws ArgumentException on invalid)
                    Dim domainName As String = idn.GetAscii(match.Groups(2).Value)

                    Return match.Groups(1).Value & domainName

                End Function

            'Normalize the domain
            email = Regex.Replace(email, "(@)(.+)$", DomainMapper,
                                  RegexOptions.None, TimeSpan.FromMilliseconds(200))

        Catch e As RegexMatchTimeoutException
            Return False

        Catch e As ArgumentException
            Return False

        End Try

        Try
            Return Regex.IsMatch(email,
                                 "^[^@\s]+@[^@\s]+\.[^@\s]+$",
                                 RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250))

        Catch e As RegexMatchTimeoutException
            Return False

        End Try

    End Function
End Class

在本例中,正则表达式模式 ^[^@\s]+@[^@\s]+\.[^@\s]+$ 按下表中的方式解释。 使用 RegexOptions.IgnoreCase 标志编译正则表达式。

模式 描述
^ 从字符串的开头部分开始匹配。
[^@\s]+ 匹配一次或多次出现的任何字符,@ 字符或空格除外。
@ 匹配 @ 字符。
[^@\s]+ 匹配一次或多次出现的任何字符,@ 字符或空格除外。
\. 匹配一个句点字符。
[^@\s]+ 匹配一次或多次出现的任何字符,@ 字符或空格除外。
$ 在字符串的结尾结束匹配。

重要

此正则表达式没有涵盖有效电子邮件地址的所有字符。 它作为示例提供,你可以按需对其进行扩展。

请参阅