【问题标题】:Regex to validate a semi-colon seperated list of emails?正则表达式验证分号分隔的电子邮件列表?
【发布时间】:2014-12-11 18:41:49
【问题描述】:

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

我需要改进此方法,以便能够处理以分号分隔的电子邮件列表。一个有效的示例字符串的格式可能很糟糕:“;; ; ; 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);
    }

【问题讨论】:

  • 对于检查电子邮件地址是否有效的非常简单的方法,请参阅该 MSDN 示例末尾的注释:“除了使用正则表达式来验证电子邮件地址,您可以使用System.Net.Mail.MailAddress 类。要确定电子邮件地址是否有效,请将电子邮件地址传递给 MailAddress.MailAddress(String) 类构造函数。"

标签: c# regex validation email csv


【解决方案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);
    }

【讨论】:

  • 您可以使用:if (!email.IsValidEmailAddress()) return false; 简化列表验证,因为在这种情况下没有必要继续使用 for 循环。最终返回变为return isnotblank;,并且可以删除valid 变量。
  • 是的。我这样做只是为了在其中放置一个断点。我经常这样做。
【解决方案2】:

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

现在它也允许空条目(没有电子邮件地址)。如果您想将其更改为至少 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*$)

【讨论】:

  • 这适用于分号分隔。但是,电子邮件地址的要求要复杂得多。您的正则表达式不匹配大约 14 个特殊字符。此外,电子邮件不能以句点或破折号开头或结尾。并且 @ 符号之前或之后不能有 peroids。
猜你喜欢
  • 2014-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多