开发者

C# Email Address validation

开发者 https://www.devze.com 2023-03-14 16:30 出处:网络
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.

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 Que开发者_如何学Cstion according to RFC standard will an email address contain aportrophe? If so how to recreate regular expression to allow apostrophe?


The regular expression below implements the official RFC 2822 standard for email addresses. 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*. It doesn't support any of the other, more...creative constructs that the RFCs allow (this list is not comprehensive by any means):

  • comments (e.g., jsmith@whizbang.com (work))
  • quoted strings (escaped text, to allow characters not allowed in an atom)
  • domain literals (e.g. foo@[123.45.67.012])
  • bang-paths (aka source routing)
  • angle addresses (e.g. John Smith <jsmith@whizbang.com>)
  • folding whitespace
  • double-byte characters in either local-part or domain (7-bit ASCII only).
  • 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). 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. ICANN actually updates the TLD list daily, though I suspect that the list doesn't actually change daily. Further, ICANN just approved a big expansion of the generic TLD namespace). 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.)

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!

0

精彩评论

暂无评论...
验证码 换一张
取 消