Проверка адреса электронной почты С#

Просто я хочу прояснить одно. Для каждого запроса клиента мы должны создать регулярное выражение таким образом, чтобы он разрешал апостроф в адресе электронной почты.

Мой вопрос в соответствии со стандартом RFC будет содержать адрес электронной почты aportrophe? Если да, то как воссоздать регулярное выражение, чтобы разрешить апостроф?

Ответ 1

Регулярное выражение ниже содержит официальный RFC 2822 стандарт для адресов электронной почты. Использование этого регулярного выражения в реальных приложениях НЕ рекомендуется. Показано, что с регулярными выражениями всегда существует компромисс между точными и практическими.

(?:[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])+)\])

Вы можете использовать упрощенный:

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

И да, апостроф разрешен в письме, если он не находится в доменном имени.

Ответ 2

Вот атрибут проверки, который я написал. Он проверяет почти все "сырые" адреса электронной почты, то есть те, которые указаны в локальном домене формы * *. Он не поддерживает какие-либо другие, более... креативные конструкции, разрешенные RFC (этот список не является исчерпывающим каким-либо образом):

  • комментарии (например, [email protected] (work))
  • цитируемые строки (экранированный текст, чтобы символы не допускались в атоме)
  • литералы домена (например, [email protected][123.45.67.012])
  • bang-paths (aka source routing)
  • угловые адреса (например, John Smith <[email protected]>)
  • складывающиеся пробелы
  • двухбайтовые символы либо в локальной части, либо в домене (только для 7-разрядного ASCII).
  • и др.

Он должен принимать почти любой адрес электронной почты, который может быть выражен таким образом

не требуя использования кавычек ("), угловых скобок ('< > ') или квадратных скобок ([]).

Не предпринимается попытка подтвердить, что самая правая dns-метка в домене является действительным TLD (домен верхнего уровня). Это потому, что список TLD намного больше, чем "большие 6" (.com,.edu,.gov,.mil,.net,.org) и 2-буквенные коды стран ISO. ICANN фактически обновляет список TLD ежедневно, хотя я подозреваю, что этот список фактически не меняется ежедневно. Кроме того, ICANN только что одобрила большое расширение общего пространства имен TLD). И некоторые адреса электронной почты не имеют того, что вы признаете в качестве TLD (знаете ли вы, что [email protected] теоретически является допустимым и распространяемым по почте? Почта на этот адрес должна быть доставлена ​​почтмейстеру в корневой зоне DNS.)

Расширение регулярного выражения для поддержки доменных литералов, это не должно быть слишком сложно.

Здесь вы идете. Используйте его в хорошем состоянии:

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 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 ;
    }

  }
}

Ура!