正则表达式验证分号分隔的电子邮件列表?

时间:2014-12-11 18:41:50

标签: c# regex validation email delimited-text

我有以下用于验证电子邮件地址的c#扩展方法。正则表达式来自Microsoft的如何:验证字符串是否在有效的电子邮件格式页面。

我需要改进此方法,以便能够处理分号分隔的电子邮件列表。一个有效的示例字符串可能格式错误:&#34 ;;; ; ; xxx.sss.xxx; ;; xxx.sss.xxx;"

    /// <summary>
    /// Validates the string is an Email Address...
    /// </summary>
    /// <param name="emailAddress"></param>
    /// <returns>bool</returns>
    public static bool IsValidEmailAddress(this string emailAddress)
    {
        var valid = true;
        var isnotblank = false;

        var email = emailAddress.Trim();
        if (email.Length > 0)
        {
            isnotblank = true;
            valid = Regex.IsMatch(email, @"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))" +
            @"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$", RegexOptions.IgnoreCase);
        }

        return (valid && isnotblank);
    }

2 个答案:

答案 0 :(得分:1)

微软的正则表达式做得非常好。但是,它并没有捕获一些奇怪的场景和一些对电子邮件有效的特殊字符。我会给你一个不同的正则表达式。选择使用与否是您的特权。

我会通过一个验证电子邮件地址的扩展方法和另一个验证列表的扩展方法来区分问题。在将每个电子邮件传递给电子邮件验证方法之前,请对其执行.trim()。所以,像这样:

    /// <summary>
    /// Validates the string is an Email Address...
    /// </summary>
    /// <param name="emailAddress"></param>
    /// <returns>bool</returns>
    public static bool IsValidEmailAddress(this string emailAddress)
    {
        var valid = true;
        var isnotblank = false;

        var email = emailAddress.Trim();
        if (email.Length > 0)
        {
            // Email Address Cannot start with period.
            // Name portion must be at least one character
            // In the Name, valid characters are:  a-z 0-9 ! # _ % & ' " = ` { } ~ - + * ? ^ | / $
            // Cannot have period immediately before @ sign.
            // Cannot have two @ symbols
            // In the domain, valid characters are: a-z 0-9 - .
            // Domain cannot start with a period or dash
            // Domain name must be 2 characters.. not more than 256 characters
            // Domain cannot end with a period or dash.
            // Domain must contain a period
            isnotblank = true;
            valid = Regex.IsMatch(email, @"\A([\w!#%&'""=`{}~\.\-\+\*\?\^\|\/\$])+@{1}\w+([-.]\w+)*\.\w+([-.]\w+)*\z", RegexOptions.IgnoreCase) &&
                !email.StartsWith("-") &&
                !email.StartsWith(".") &&
                !email.EndsWith(".") && 
                !email.Contains("..") &&
                !email.Contains(".@") &&
                !email.Contains("@.");
        }

        return (valid && isnotblank);
    }

    /// <summary>
    /// Validates the string is an Email Address or a delimited string of email addresses...
    /// </summary>
    /// <param name="emailAddress"></param>
    /// <returns>bool</returns>
    public static bool IsValidEmailAddressDelimitedList(this string emailAddress, char delimiter = ';')
    {
        var valid = true;
        var isnotblank = false;

        string[] emails = emailAddress.Split(delimiter);

        foreach (string e in emails)
        {
            var email = e.Trim();
            if (email.Length > 0 && valid) // if valid == false, no reason to continue checking
            {
                isnotblank = true;
                if (!email.IsValidEmailAddress())
                {
                    valid = false;
                }
            }
        }
        return (valid && isnotblank);
    }

答案 1 :(得分:0)

您可以使用以下正则表达式允许除分号之外的分号和(可选)空格分隔的多封电子邮件。它也会接受不以分号结尾的单个电子邮件地址。

现在它也允许空条目(没有电子邮件地址)。如果您想将其更改为至少为1,则将最终*替换为+至少需要一个地址。

(([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)(\s*;\s*|\s*$))*

如果你想允许使用逗号和分号,可以使用以下内容:

(\s*;\s*|\s*$)

到此:

(\s*(;|,)\s*|\s*$)