简体   繁体   English

C#电子邮件地址验证

[英]C# Email Address validation

Just I want to clarify one thing. 我想澄清一件事。 Per client request we have to create a regular expression in such a way that it should allow apostrophe in email address. 根据客户端请求,我们必须创建一个正则表达式,以便它允许在电子邮件地址中使用撇号。

My Question according to RFC standard will an email address contain aportrophe? 我的问题根据RFC标准,电子邮件地址是否包含aportrophe? If so how to recreate regular expression to allow apostrophe ? 如果是这样,如何重新创建正则表达式以允许撇号

The regular expression below implements the official RFC 2822 standard for email addresses. 下面的正则表达式实现了电子邮件地址的官方RFC 2822标准。 Using this regular expression in actual applications is NOT recommended. 不建议在实际应用程序中使用此正则表达式。 It is shown to illustrate that with regular expressions there's always a trade-off between what's exact and what's practical. 它表明,使用正则表达式总是在精确和实际之间进行权衡。

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])

You could use the simplified one: 您可以使用简化的:

[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?

And yes, apostrophe is allowed in the email, as long as it is not in domain name. 是的,只要撇号不在域名中,就允许在电子邮件中使用撇号。

Here's the validation attribute I wrote. 这是我写的验证属性。 It validates pretty much every "raw" email address, that is those of the form local-part @*domain*. 它几乎验证了每个“原始”电子邮件地址,即local-part @ * domain *形式的电子邮件地址。 It doesn't support any of the other, more...creative constructs that the RFCs allow (this list is not comprehensive by any means): 它不支持RFC允许的任何其他更多......创造性结构(此列表无论如何都不全面):

  • comments (eg, jsmith@whizbang.com (work) ) 评论(例如, jsmith@whizbang.com (work)
  • quoted strings (escaped text, to allow characters not allowed in an atom) 引用的字符串(转义文本,允许原子中不允许的字符)
  • domain literals (eg foo@[123.45.67.012] ) 域文字(例如foo@[123.45.67.012]
  • bang-paths (aka source routing) bang-paths(又名源路由)
  • angle addresses (eg John Smith <jsmith@whizbang.com> ) 角度地址(例如John Smith <jsmith@whizbang.com>
  • folding whitespace 折叠空白
  • double-byte characters in either local-part or domain (7-bit ASCII only). 本地部分域中的双字节字符(仅限7位ASCII)。
  • etc. 等等

It should accept almost any email address that can be expressed thusly 它应该接受几乎任何可以表达的电子邮件地址

  • foo.bar@bazbat.com

without requiring the use of quotes ( " ), angle brackets ('<>') or square brackets ( [] ). 无需使用引号( " ),尖括号('<>')或方括号( [] )。

No attempt is made to validate that the rightmost dns label in the domain is a valid TLD (top-level domain). 没有尝试验证域中最右边的DNS标签是否是有效的TLD(顶级域)。 That is because the list of TLDs is far larger now than the "big 6" (.com, .edu, .gov, .mil, .net, .org) plus 2-letter ISO country codes. 这是因为TLD列表现在比“大6”(.com,.edu,.gov,.mil,.net,.org)加上2个字母的ISO国家/地区代码要大得多。 ICANN actually updates the TLD list daily , though I suspect that the list doesn't actually change daily. ICANN实际上每天更新TLD列表 ,但我怀疑该列表实际上并未每天更改。 Further, ICANN just approved a big expansion of the generic TLD namespace ). 此外, ICANN刚刚批准了通用TLD命名空间的大规模扩展 And some email addresses don't have what you're recognize as a TLD (did you know that postmaster@. is theoretically valid and mailable? Mail to that address should get delivered to the postmaster of the DNS root zone.) 有些电子邮件地址没有你认可的TLD(你知道postmaster@.理论上是有效且可邮寄的吗?到该地址的邮件应该交付给DNS根区域的邮局主管。)

Extending the regular expression to support domain literals, it shouldn't be too difficult. 扩展正则表达式以支持域文字,这应该不会太困难。

Here you go. 干得好。 Use it in good health: 使用它健康:

using System;
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;

namespace ValidationHelpers
{
  [AttributeUsage( AttributeTargets.Property | AttributeTargets.Field , AllowMultiple = false )]
  sealed public class EmailAddressValidationAttribute : ValidationAttribute
  {
    static EmailAddressValidationAttribute()
    {
      RxEmailAddress = CreateEmailAddressRegex();
      return;
    }

    private static Regex CreateEmailAddressRegex()
    {
      // references: RFC 5321, RFC 5322, RFC 1035, plus errata.
      string atom             = @"([A-Z0-9!#$%&'*+\-/=?^_`{|}~]+)"                 ;
      string dot              = @"(\.)"                                            ;
      string dotAtom          =  "(" + atom + "(" + dot + atom + ")*" + ")"        ;
      string dnsLabel         = "([A-Z]([A-Z0-9-]{0,61}[A-Z0-9])?)"                ;
      string fqdn             = "(" + dnsLabel + "(" + dot + dnsLabel + ")*" + ")" ;

      string localPart        = "(?<localpart>" + dotAtom + ")"      ;
      string domain           = "(?<domain>" + fqdn + ")"            ;
      string emailAddrPattern = "^" + localPart + "@" + domain + "$" ;

      Regex instance = new Regex( emailAddrPattern , RegexOptions.Singleline | RegexOptions.IgnoreCase );
      return instance;
    }

    private static Regex RxEmailAddress;

    public override bool IsValid( object value )
    {
      string s      = Convert.ToString( value ) ;
      bool   fValid = string.IsNullOrEmpty( s ) ;

      // we'll take an empty field as valid and leave it to the [Required] attribute to enforce that it's been supplied.
      if ( !fValid )
      {
        Match m = RxEmailAddress.Match( s ) ;

        if ( m.Success )
        {
          string emailAddr              = m.Value ;
          string localPart              = m.Groups[ "localpart" ].Value ;
          string domain                 = m.Groups[ "domain"    ].Value ;
          bool   fLocalPartLengthValid  = localPart.Length >= 1 && localPart.Length <=  64 ;
          bool   fDomainLengthValid     = domain.Length    >= 1 && domain.Length    <= 255 ;
          bool   fEmailAddrLengthValid  = emailAddr.Length >= 1 && emailAddr.Length <= 256 ; // might be 254 in practice -- the RFCs are a little fuzzy here.

          fValid = fLocalPartLengthValid && fDomainLengthValid && fEmailAddrLengthValid ;

        }
      }

      return fValid ;
    }

  }
}

Cheers! 干杯!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM