Código C # para validar o endereço de email


461

Qual é o código mais elegante para validar que uma string é um endereço de email válido?




existem muitas outras validações importantes, não apenas a string, é melhor verificar se o email existe neste servidor smtp ou se o usuário está inserindo algum email .. etc. ou usar a API que lida com isso para garantir que o email está correto como ver-email.com
Amr Magdy


Respostas:


784

Que tal isso?

bool IsValidEmail(string email)
{
    try {
        var addr = new System.Net.Mail.MailAddress(email);
        return addr.Address == email;
    }
    catch {
        return false;
    }
}

Para esclarecer, a pergunta é perguntar se uma sequência específica é uma representação válida de um endereço de email, não se um endereço de email é um destino válido para enviar uma mensagem. Para isso, a única maneira real é enviar uma mensagem para confirmar.

Observe que os endereços de email são mais tolerantes do que você imagina. Todas estas são formas perfeitamente válidas:

  • roda dentada @
  • "roda dentada da laranja" @ example.com
  • 123@$.xyz

Para a maioria dos casos de uso, um falso "inválido" é muito pior para seus usuários e provas futuras do que um falso "válido". Aqui está um artigo que costumava ser a resposta aceita para esta pergunta (essa resposta já foi excluída). Ele tem muito mais detalhes e algumas outras idéias de como resolver o problema.

O fornecimento de verificações de sanidade ainda é uma boa idéia para a experiência do usuário. Supondo que o endereço de e-mail seja válido, você pode procurar domínios de nível superior conhecidos, verificar se há um registro MX no domínio, verificar erros de ortografia em nomes de domínio comuns (gmail.cmo) etc. Em seguida, apresente um aviso informando ao usuário a chance de dizer "sim, meu servidor de email realmente permite 🌮🍳🎁 como endereço de email".


Quanto ao uso de manipulação de exceção para a lógica de negócios, concordo que isso é algo a ser evitado. Mas esse é um daqueles casos em que a conveniência e a clareza podem superar o dogma.

Além disso, se você fizer mais alguma coisa com o endereço de e-mail, provavelmente envolverá transformá-lo em um endereço de email. Mesmo se você não usar essa função exata, provavelmente desejará usar o mesmo padrão. Você também pode verificar tipos específicos de falha capturando diferentes exceções : formato nulo, vazio ou inválido.


De acordo com o comentário de Stuart, isso compara o endereço final com a string original em vez de sempre retornar true. MailAddress tenta analisar uma seqüência de caracteres com espaços nas partes "Nome para exibição" e "Endereço", para que a versão original retornasse falsos positivos.


--- Leitura adicional ---

Documentação para System.Net.Mail.MailAddress

Explicação do que constitui um endereço de email válido


23
Na verdade, isso não está incorreto. a @ a é um endereço de email válido. Consulte haacked.com/archive/2007/08/21/… De fato, esse método retorna resultados incorretos se você usar um endereço entre aspas.
Cogwheel

53
+1: esta é a melhor resposta se você estiver usando as System.Net.Mailclasses para enviar e-mail, o que provavelmente será se estiver usando o .NET. Decidimos usar esse tipo de validação simplesmente porque não faz sentido aceitar endereços de email - mesmo válidos - para os quais não podemos enviar emails.
Greg Beech

24
Eu não recomendo. Retorna verdadeiro:IsValidEmail("this is not valid@email$com");
Kakashi

15
Muitos dos problemas parecem ocorrer porque o MailAddress também tenta analisar o DisplayName; portanto, "single space@domain.com" analisa o DisplayName "single" e o endereço "space@domain.com". Uma correção para isso é: return (addr.Address == email);
Stuart

18
Eu gosto disso; Eu não entendo a compulsão mais restritiva do que as especificações reais. Falsos negativos são muito piores do que falsos positivos ( "o que quer dizer meu e-mail é inválido? ")
Casey

242

Esta é uma pergunta antiga, mas todas as respostas que encontrei no SO, incluindo as mais recentes, são respondidas de maneira semelhante a esta. No entanto, no .Net 4.5 / MVC 4, você pode adicionar a validação de endereço de email a um formulário, adicionando a anotação [EmailAddress] de System.ComponentModel.DataAnnotations, então fiquei pensando por que não poderia usar apenas a funcionalidade interna. Rede em geral.

Isso parece funcionar e me parece bastante elegante:

using System.ComponentModel.DataAnnotations;

class ValidateSomeEmails
{
    static void Main(string[] args)
    {
        var foo = new EmailAddressAttribute();
        bool bar;
        bar = foo.IsValid("someone@somewhere.com");         //true
        bar = foo.IsValid("someone@somewhere.co.uk");       //true
        bar = foo.IsValid("someone+tag@somewhere.net");     //true
        bar = foo.IsValid("futureTLD@somewhere.fooo");      //true

        bar = foo.IsValid("fdsa");                          //false
        bar = foo.IsValid("fdsa@");                         //false
        bar = foo.IsValid("fdsa@fdsa");                     //false
        bar = foo.IsValid("fdsa@fdsa.");                    //false

        //one-liner
        if (new EmailAddressAttribute().IsValid("someone@somewhere.com"))
            bar = true;    
    }
}

4
Legal, embora seja decepcionante que a MS não possa fazer isso concordar com sua própria documentação . Isso é rejeitado por js@proseware.com9
Casey

13
Observe que EmailAddressAttributeé menos permissivo do que, System.Net.Mail.MailAddresspor exemplo, MailAddressaceita um endereço para um TLD. Apenas algo a ter em mente se você precisar ser o mais permissivo possível.
Aaroninus

5
@ Roda dentada: se a resposta estiver em algum lugar nos comentários, provavelmente deverá ser adicionada ao corpo principal da resposta.
hofnarwillie

6
@hofnarwillie: está no corpo principal, mas os comentários são elaborados. Se seu objetivo é não irritar seus usuários, sua validação não deve ser mais restritiva que a especificação. A única maneira de verificar verdadeiramente se um email é válido é enviar uma mensagem de teste.
Cogwheel

4
Observe que foo.IsValid(null);retorna true.
urig

62

Eu uso esse método de liner único que faz o trabalho para mim

using System.ComponentModel.DataAnnotations;
public bool IsValidEmail(string source)
{
    return new EmailAddressAttribute().IsValid(source);
}

Pelos comentários, isso "falhará" se o source(o endereço de email) for nulo.

public static bool IsValidEmailAddress(this string address) => address != null && new EmailAddressAttribute().IsValid(address);

1
Isso não funciona para mim; Eu recebo: "'Anotações de dados' não existe ... está faltando uma referência de montagem?" Qual referência eu preciso adicionar?
B. Clay Shannon

Isso retornará true se a origem for nula. Consulte msdn.microsoft.com/en-us/library/hh192424 "true se o valor especificado for válido ou nulo; caso contrário, false".
jao

2
Uma versão melhor:public static Boolean IsValidMailAddress(this String pThis) => pThis == null ? false : new EmailAddressAttribute().IsValid(pThis);
Sebastian Hofmann

7
Ou melhor:public static bool IsValidEmailAddress(this string address) => address != null && new EmailAddressAttribute().IsValid(address);
Patrik Melander

1
Eu não acho que esse método de extensão silenciosamente retorne falsepara seqüências nulas. É por isso que proponho a (melhor ainda melhor) ++ versão: public static bool IsValidEmailAddress(this string address) => new EmailAddressAttribute().IsValid(address ?? throw new ArgumentNullException());. Agora irei encontrar a Igreja Reformada dos Versionistas Ainda Melhores.
Marc.2377

41

.net 4.5 adicionado System.ComponentModel.DataAnnotations.EmailAddressAttribute

Você pode procurar a fonte do EmailAddressAttribute , este é o Regex que ele usa internamente:

const string pattern = @"^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$";

2
Infelizmente, o EmaillAddressAttribute permite Ñ que não é um caractere válido para email
BZ

16
@BZ Sim, é. Por que você acha que não é?
30814 Casey

@ Chad Grant: Esta é uma versão C #. Você pode fornecer um VB.Net? Como isso escapará caracteres como \\ to \ ou você pode fornecer uma string literalmente.
Nikhil Agrawal

3
Isso funciona, mas não se esqueça, RegexOptions.IgnoreCaseporque esse padrão não permite letras maiúsculas explicitamente!
Chris

1
Observe que o Regex é muito deliberado: "Este atributo fornece validação de email do lado do servidor equivalente à validação de jquery e, portanto, compartilha a mesma expressão regular".
Ohad Schneider

38

Peguei a resposta de Phil do nº 1 e criei esta classe. Chame assim:bool isValid = Validator.EmailIsValid(emailString);

Aqui está a classe:

using System.Text.RegularExpressions;

public static class Validator
{

    static Regex ValidEmailRegex = CreateValidEmailRegex();

    /// <summary>
    /// Taken from http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx
    /// </summary>
    /// <returns></returns>
    private static Regex CreateValidEmailRegex()
    {
        string validEmailPattern = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|"
            + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)"
            + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";

        return new Regex(validEmailPattern, RegexOptions.IgnoreCase);
    }

    internal static bool EmailIsValid(string emailAddress)
    {
        bool isValid = ValidEmailRegex.IsMatch(emailAddress);

        return isValid;
    }
}

5
Apenas um pequeno, mas eu usaria: return (! String.IsNullOrEmpty (emailAddress)) && ValidEmailRegex.IsMatch (emailAddress);
Marc

Este é apenas horror :)
Alexandru Dicu

31

Pessoalmente, eu diria que você deve apenas garantir que haja um símbolo @, com possivelmente a. personagem. Você pode usar muitas expressões regulares de correção variável, mas acho que a maioria deixa de fora endereços de email válidos ou deixa passar endereços inválidos. Se as pessoas quiserem inserir um endereço de e-mail falso, eles o inserirão. Se você precisar verificar se o endereço de email é legítimo e se a pessoa está no controle desse endereço de email, será necessário enviar um email com um link codificado especial para que eles possam verificar se realmente é um endereço real.


6
Pessoalmente, acho que você deve fazer um pouco mais de validação do que isso. Alguém pode tentar o endereço de e-mail de Bobby Table ou pior.
Luke Quinane 02/09/09

31
O que há de errado com o endereço de email da tabela de bobby se você estiver usando instruções preparadas. Estamos falando de endereços de email válidos, e não de outras coisas que não têm nada a ver com o que constitui um endereço de email válido, como como fazer consultas SQL adequadamente para que você não tenha problemas de injeção de SQL.
Kibbee

Eu acho que você não sabe o que alguém colocará lá, mas uma pessoa mal-intencionada sabe que o valor pode eventualmente ser alimentado no seu sistema de correio. Eu preferiria me aprofundar na defesa e ser um pouco mais rigoroso.
Luke Quinane 02/09/09

10
É para o sistema de correio se preocupar. Eu não rejeitaria endereços de email perfeitamente válidos apenas porque poderia ser um problema de segurança em algum outro sistema. Se todo o seu servidor de email precisar de um endereço de email incorreto para causar problemas de segurança, você provavelmente deverá mudar para outro servidor.
Kibbee

4
A defesa em profundidade só funciona se cada nível da sua cebola de segurança não estiver podre. Uma camada podre significa que você estraga a cebola inteira. Rejeitar "foo@example.com.au" porque você deseja se defender contra vulnerabilidades na codificação µ-law da Sun não faz sentido, faz? Não ria, aconteceu comigo. A razão pela qual estou aqui comentando é que o Medicare Australia não permite endereços ".au", apenas ".com". Leia também Mark Swanson, "Como não validar email", mdswanson.com/blog/2013/10/14/…
ManicDee

17

Eu acho que a melhor maneira é a seguinte:

    public static bool EmailIsValid(string email)
    {
        string expression = "\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";

        if (Regex.IsMatch(email, expression))
        {
            if (Regex.Replace(email, expression, string.Empty).Length == 0)
            {
                return true;
            }
        }
        return false;
    }

Você pode ter essa função estática em uma classe geral.


Esta resposta não aceita um endereço com um TLD na parte do domínio.
Simone

15

Código curto e preciso

string Email = txtEmail.Text;
if (Email.IsValidEmail())
{
   //use code here 
}

public static bool IsValidEmail(this string email)
{
  string pattern = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|" + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)" + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";    
  var regex = new Regex(pattern, RegexOptions.IgnoreCase);    
  return regex.IsMatch(email);
}

2
Obrigado pela solução
Jack Gajanan

Eu tive que alterar IsValidEmail público bool estático (este email de seqüência de caracteres) para IsValidEmail público bool estático (email de seqüência de caracteres) para evitar ISTO: stackoverflow.com/questions/10412233/…
Goner Doug

. @Goner Doug, este functionlity funcionará como este (bandeira bool = EmailAddress.IsValidEmail ())
Naveen

2
o "THIS" precisava ser removido para evitar problemas no compilador quando adicionado ao meu formulário.
Goner Doug

@ Goner Doug, sua funcionalidade funcionará assim. string email = "abc@xyz.com"; if (email.IsValidEmail ()) {return false; } else {return true;}
Naveen

14

A maneira mais elegante é usar os métodos incorporados do .Net.

Estes métodos:

  • São experimentados e testados. Esses métodos são usados ​​em meus próprios projetos profissionais.

  • Use expressões regulares internamente, confiáveis ​​e rápidas.

  • Feito pela Microsoft para C #. Não há necessidade de reinventar a roda.

  • Retornar um resultado booleano. Verdadeiro significa que o email é válido.

Para usuários do .Net 4.5 e superior

Adicione esta referência ao seu projeto:

System.ComponentModel.DataAnnotations

Agora você pode usar o seguinte código:

(new EmailAddressAttribute().IsValid("youremailhere@test.test"));

Exemplo de uso

Aqui estão alguns métodos para declarar:

protected List<string> GetRecipients() // Gets recipients from TextBox named `TxtRecipients`
{
    List<string> MethodResult = null;

    try
    {
        List<string> Recipients = TxtRecipients.Text.Replace(",",";").Replace(" ", "").Split(';').ToList();

        List<string> RecipientsCleaned = new List<string>();

        foreach (string Recipient in RecipientsCleaned)
        {
            if (!String.IsNullOrWhiteSpace(Recipient))
            {
                RecipientsNoBlanks.Add(Recipient);

            }

        }

        MethodResult = RecipientsNoBlanks;

    }
    catch//(Exception ex)
    {
        //ex.HandleException();
    }

    return MethodResult;

}


public static bool IsValidEmailAddresses(List<string> recipients)
{
    List<string> InvalidAddresses = GetInvalidEmailAddresses(recipients);

    return InvalidAddresses != null && InvalidAddresses.Count == 0;

}

public static List<string> GetInvalidEmailAddresses(List<string> recipients)
{
    List<string> MethodResult = null;

    try
    {
        List<string> InvalidEmailAddresses = new List<string>();

        foreach (string Recipient in recipients)
        {
            if (!(new EmailAddressAttribute().IsValid(Recipient)) && !InvalidEmailAddresses.Contains(Recipient))
            {
                InvalidEmailAddresses.Add(Recipient);

            }

        }

        MethodResult = InvalidEmailAddresses;

    }
    catch//(Exception ex)
    {
        //ex.HandleException();

    }

    return MethodResult;

}

... e código demonstrando-os em ação:

List<string> Recipients = GetRecipients();

bool IsValidEmailAddresses = IsValidEmailAddresses(Recipients);

if (IsValidEmailAddresses)
{
    //Emails are valid. Your code here

}
else
{
    StringBuilder sb = new StringBuilder();

    sb.Append("The following addresses are invalid:");

    List<string> InvalidEmails = GetInvalidEmailAddresses(Recipients);

    foreach (string InvalidEmail in InvalidEmails)
    {
        sb.Append("\n" + InvalidEmail);

    }

    MessageBox.Show(sb.ToString());

}

Além disso, este exemplo:

  • Estende-se além das especificações, uma vez que uma única cadeia é usada para conter 0, um ou mais endereços de e-mail separados por ponto e vírgula ; .
  • Demonstra claramente como usar o método IsValid do objeto EmailAddressAttribute.

Alternativa, para usuários de uma versão do .Net menor que 4.5

Para situações em que o .Net 4.5 não está disponível, eu uso a seguinte solução:

Especificamente, eu uso:

public static bool IsValidEmailAddress(string emailAddress)
{
    bool MethodResult = false;

    try
    {
        MailAddress m = new MailAddress(emailAddress);

        MethodResult = m.Address == emailAddress;

    }
    catch //(Exception ex)
    {
        //ex.HandleException();

    }

    return MethodResult;

}

public static List<string> GetInvalidEmailAddresses(List<string> recipients)
{
    List<string> MethodResult = null;

    try
    {
        List<string> InvalidEmailAddresses = new List<string>();

        foreach (string Recipient in recipients)
        {
            if (!IsValidEmail(Recipient) && !InvalidEmailAddresses.Contains(Recipient))
            {
                InvalidEmailAddresses.Add(Recipient);

            }

        }

        MethodResult = InvalidEmailAddresses;

    }
    catch //(Exception ex)
    {
        //ex.HandleException();

    }

    return MethodResult;

}

1
@ThomasAyoub Não vi uma resposta EmailAddressAttribute e nenhuma resposta que use o novo MailAddress () com uma verificação na entrada == .Address, então eu acho que é bastante útil. Sem ler os comentários, a resposta aceita está bastante errada. Um novo endereço de email ("Foobar Some@thing.com") prova isso.
Jan

@Jan fwiw, Manik venceu o Knickerless EmailAddressAttributepor pouco menos de quatro meses, apesar de este pegar o nullproblema.
Ruffin

7

Para ser honesto, no código de produção, o melhor que faço é procurar um @símbolo.

Nunca estou em um local para validar completamente os e-mails. Você sabe como eu vejo se era realmente válido? Se foi enviado. Se não, é ruim, se é, a vida é boa. É tudo o que preciso saber.


6

Acho que esse regex é uma boa opção entre verificar algo além da marca @ e aceitar casos extremos estranhos:

^[^@\s]+@[^@\s]+(\.[^@\s]+)+$

Isso fará com que você coloque algo em torno da marca @ e coloque pelo menos um domínio com aparência normal.


Eu vim com a mesma regex;) ele permite charachters inválidos embora
Stefan

Esta resposta não aceita um TLD na parte do domínio.
Simone

@Simone provavelmente ninguém faz ter endereços de e-mail com o TLD na parte de domínio embora na prática: serverfault.com/a/721929/167961 nota nos comentários que podem ser proibidos nos dias de hoje
Matthew Bloqueio

@MatthewLock Poderia ser um endereço de intranet? Gosta bob@companyinternal?
Simone

@ Simone, alguém na vida real realmente usa esse esquema?
Matthew Lock

4

A validação do endereço de email não é tão fácil quanto parece. Na verdade, é teoricamente impossível validar completamente um endereço de email usando apenas uma expressão regular.

Confira meu post sobre isso para uma discussão sobre o assunto e uma implementação de F # usando FParsec. [/ shameless_plug]


1
Gostei da sua lista de abordagens alternativas; muito interessante.
Luke Quinane 02/09/09

1
Artigo interessante. Mas, falando sério, quem está colocando comentários, e aninhados, nos endereços de email?
Matthew Lock

3
@matthew Não sei por que a IETF sequer permitiu isso, mas é possível , portanto, uma validação completa deve levar em consideração.
Mauricio Scheffer

4

Aqui está a minha resposta - a solução de Phil falha em domínios de letra única como "someone@q.com". Acredite ou não, isso é usado =) (vai para centurylink, por exemplo).

A resposta de Phil também funcionará apenas com o padrão PCRE ... então o C # aceitará, mas o javascript está bombando. É muito complexo para javascript. Portanto, você não pode usar a solução de Phil para atributos de validação de mvc.

Aqui está o meu regex. Funcionará bem com os atributos de validação do MVC.
- Tudo antes do @ é simplificado, para que pelo menos o javascript funcione. Estou bem relaxando a validação aqui, desde que o servidor do Exchange não me dê um 5.1.3. - Tudo após o @ é a solução de Phil modificada para domínios de uma letra.

public const string EmailPattern =
        @"^\s*[\w\-\+_']+(\.[\w\-\+_']+)*\@[A-Za-z0-9]([\w\.-]*[A-Za-z0-9])?\.[A-Za-z][A-Za-z\.]*[A-Za-z]$";

Para as pessoas que sugerem o uso de system.net.mail MailMessage (), essa coisa é MUITO flexível. Claro, o C # aceitará o email, mas o servidor do Exchange sofrerá um erro de tempo de execução 5.1.3 assim que você tentar enviar o email.


essa parece ser a melhor resposta mais atenciosa / razoável / do mundo real, obrigado Ralph!
Fattie 24/03

esta é a melhor resposta até agora! Não acredito que uma solução ruim que aceite basket@ballcomo endereço de e-mail válido tenha recebido a resposta correta e todos os votos positivos. Obrigado mesmo assim!
disasterkid

Obrigado, esta é a melhor solução e deve ser aceita como resposta.
Bat_Programmer

3

Se você quer realmente saber se um endereço de e-mail é válido ... peça ao trocador de e-mail para provar isso, não é necessário regex. Eu posso fornecer o código, se solicitado.

As etapas gerais são as seguintes: 1. o endereço de email possui uma parte de nome de domínio? (índice de @> 0) 2. usando uma consulta DNS, pergunte se o domínio tem um trocador de correio 3. abra a conexão tcp com o trocador de correio 4. usando o protocolo smtp, abra uma mensagem para o servidor usando o endereço de email como destinatário 5. analisar a resposta do servidor. 6. saia da mensagem se você chegou até aqui, tudo está bem.

Isso é como você pode imaginar, muito caro em termos de tempo e depende do smtp, mas funciona.


Você criou falsificações, stubs e / ou zombarias para essas interfaces?
Mark A

1
Isso não vai funcionar. O protocolo smtp para verificar um endereço de email LONG foi descontinuado / não foi usado. É considerado uma má prática habilitá-lo nos servidores de email, pois os remetentes de spam usam essa funcionalidade.
Chad Grant #

Manterei sua sugestão até o ponto 2. Muito mais à prova do futuro do que procurar um padrão de nome de domínio conhecido.
Simone

Nitpicking, mas definir "tem um trocador de correio" ? Se não existirem registros MX, o SMTP deverá retornar ao registro A / AAAA, conforme RFC2821 / 5321. Se um registro MX existir, ele ainda pode não indicar que existe um trocador de correio (RFC7505). Realmente, a única maneira é enviar-lhes um e-mail com um link call-to-action, e esperar por eles para responder ...
jimbobmcgee

2

De um modo geral, uma expressão regular para validar endereços de email não é algo fácil de se apresentar; no momento da redação deste artigo, a sintaxe de um endereço de email deve seguir um número relativamente alto de padrões e a implementação de todos eles em uma expressão regular é praticamente inviável!

Eu sugiro que você experimente a nossa EmailVerify.NET , uma biblioteca .NET madura que pode validar endereços de e-mail depois de tudo os padrões atuais da IETF (RFC 1123, RFC 2821, RFC 2822, RFC 3696, RFC 4291, RFC 5321 e RFC 5322) , testa os registros DNS relacionados, verifica se as caixas de correio de destino podem aceitar mensagens e até podem dizer se um determinado endereço está disponível ou não.

Isenção de responsabilidade: Eu sou o desenvolvedor principal deste componente.


Impressionante! "Em seguida, ele tenta entrar em contato com o trocador de mensagens responsável pelo endereço de email fornecido e inicia um diálogo SMTP falso com esse servidor, emulando um servidor de email real. Dessa forma, garante que o servidor possa lidar com emails do endereço. Muitos servidores SMTP realmente devolver respostas falsas positivas como uma proteção contra spammers: para superar esse problema, EmailVerify para .NET, finalmente, tenta consultar o permutador de email de destino várias vezes com diferentes endereços fabricadas ".
Mateus bloqueio

Obrigado, @MatthewLock;)
Efran Cobisi

Legal, mas só vejo edições pagas. Algum plano para uma comunidade / edição OpenSource?
Ohad Schneider

1
@OhadSchneider Sim: estamos oferecendo uma versão gratuita da nossa tecnologia de validação de email por meio do Verifalia, nosso serviço de verificação de email SaaS . A Verifalia vem com SDKs gratuitos e de código aberto para as principais plataformas de desenvolvimento de software, incluindo .NET .
Efran Cobisi

2
For the simple email like goerge@xxx.com, below code is sufficient. 

 public static bool ValidateEmail(string email)
        {
            System.Text.RegularExpressions.Regex emailRegex = new System.Text.RegularExpressions.Regex(@"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$");
            System.Text.RegularExpressions.Match emailMatch = emailRegex.Match(email);
            return emailMatch.Success;
        }

Não será possível validar a@b.info como um endereço de email válido.
Ray Cheng

2

Caso esteja usando o FluentValidation, você pode escrever algo simples assim:

public cass User
{
    public string Email { get; set; }
}

public class UserValidator : AbstractValidator<User>
{
    public UserValidator()
    {
        RuleFor(x => x.Email).EmailAddress().WithMessage("The text entered is not a valid email address.");
    }
}

// Validates an user. 
var validationResult = new UserValidator().Validate(new User { Email = "açflkdj" });

// This will return false, since the user email is not valid.
bool userIsValid = validationResult.IsValid;

2

uma pequena modificação na resposta @Cogwheel

public static bool IsValidEmail(this string email)
{
  // skip the exception & return early if possible
  if (email.IndexOf("@") <= 0) return false;

  try
  {
    var address = new MailAddress(email);
    return address.Address == email;
  }
  catch
  {
    return false;
  }
}

Isso não parece ajudar ... Console.WriteLine(MailAddress("asdf@asdf.").Address);gera "asdf @ asdf.", Que não é válido.
Langdon

.net parece ter sua própria definição de válido. discussão
waitforit

2

Há muitas respostas fortes aqui. No entanto, recomendo dar um passo atrás. O @Cogwheel responde à pergunta https://stackoverflow.com/a/1374644/388267 . No entanto, pode ser caro em um cenário de validação em massa, se muitos dos endereços de email que estão sendo validados forem inválidos. Sugiro que empregemos um pouco de lógica antes de entrarmos no bloco try-catch. Eu sei que o código a seguir pode ser escrito usando o RegEx, mas pode ser caro para os novos desenvolvedores entenderem. Este é o meu valor de dois centavos:

    public static bool IsEmail(this string input)
    {
        if (string.IsNullOrWhiteSpace(input)) return false;

        // MUST CONTAIN ONE AND ONLY ONE @
        var atCount = input.Count(c => c == '@');
        if (atCount != 1) return false;

        // MUST CONTAIN PERIOD
        if (!input.Contains(".")) return false;

        // @ MUST OCCUR BEFORE LAST PERIOD
        var indexOfAt = input.IndexOf("@", StringComparison.Ordinal);
        var lastIndexOfPeriod = input.LastIndexOf(".", StringComparison.Ordinal);
        var atBeforeLastPeriod = lastIndexOfPeriod > indexOfAt;
        if (!atBeforeLastPeriod) return false;

        // CODE FROM COGWHEEL'S ANSWER: https://stackoverflow.com/a/1374644/388267 
        try
        {
            var addr = new System.Net.Mail.MailAddress(input);
            return addr.Address == input;
        }
        catch
        {
            return false;
        }
    }

2

A resposta mais votada do @Cogwheel é a melhor resposta, no entanto, tentei implementar o trim()método string, para aparar todo o espaço em branco do usuário, do início ao fim. Verifique o código abaixo para obter exemplos completos -

bool IsValidEmail(string email)
{
    try
    {
        email = email.Trim();
        var addr = new System.Net.Mail.MailAddress(email);
        return addr.Address == email;
    }
    catch
    {
        return false;
    }
}

O risco disso é que você está validando um endereço de email diferente da origem, pensando que pode enviar por e-mail para a versão não cortada (neste caso) do endereço de email especificado. Uma abordagem melhor seria criar um método separado SanitizeEmail(string email), usando o resultado desse método para validar e enviar o email para.
Marco de Zeeuw

1
private static bool IsValidEmail(string emailAddress)
{
    const string validEmailPattern = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|"
                                     + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)"
                                     + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";

    return new Regex(validEmailPattern, RegexOptions.IgnoreCase).IsMatch(emailAddress);
}

1

Verifique se a sequência de e-mail está no formato correto ou incorreto ao System.Text.RegularExpressions:

    public static bool IsValidEmailId(string InputEmail)
    {
        Regex regex = new Regex(@"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$");
        Match match = regex.Match(InputEmail);
        if (match.Success)
            return true;
        else
            return false;
    }

    protected void Email_TextChanged(object sender, EventArgs e)
    {
        String UserEmail = Email.Text;
        if (IsValidEmailId(UserEmail))
        {
            Label4.Text = "This email is correct formate";
        }
        else
        {
            Label4.Text = "This email isn't correct formate";
        }
    }

1

/ Usando o Regex interno usado na criação do "novo EmailAddressAttribute ();" componente em .Net4.5 >>> using System.ComponentModel.DataAnnotations; // Para validar um endereço de email ...... Testado e funcionando.

public bool IsEmail(string email)
{
    if (String.IsNullOrEmpty(email))
    {   return false;  }
    try
    {
        Regex _regex = new Regex("^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])" +
                "+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)" +
                "((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|" +
                "[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\u" +
                "FDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|" +
                "(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|" +
                "[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900" +
                "-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFF" +
                "EF])))\\.?$", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled);
        return _regex.IsMatch(email);
    }
    catch (RegexMatchTimeoutException)
    {
        return false;
    }
}

Além disso, você pode usar isso:

http://msdn.microsoft.com/en-us/library/01escwtf(v=vs.110).aspx


diz verdadeiro para este email: "fulya_42_@hotmail.coö" e lança erro na API do mandrill
MonsterMMORPG

1
Primeiro, o email é válido wrt example@example.co ou example@example.com .... O email tem toda a sequência e critério válidos, exceto o último caractere "ö" e você pode adicionar facilmente uma condição simples para validar esse caractere . Segundo, não tenho certeza sobre o erro da API do mandrill, convém verificar seu método de uso bcos. Usei essa validação em alguns outros ambientes / APIs e isso tem sido bom para mim.
Aina Ademola C

1

Eu resumi a resposta de Poyson 1 da seguinte maneira:

public static bool IsValidEmailAddress(string candidateEmailAddr)
{
    string regexExpresion = "\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";
    return (Regex.IsMatch(candidateEmailAddr, regexExpresion)) && 
           (Regex.Replace(candidateEmailAddr, regexExpresion, string.Empty).Length == 0);
}

1

A maneira simples de identificar o emailid é válida ou não.

public static bool EmailIsValid(string email)
{
        return Regex.IsMatch(email, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
}

1

Há um problema de cultura no regex em C # em vez de js. Portanto, precisamos usar regex no modo americano para verificação de e-mail. Se você não usar o modo ECMAScript, os caracteres especiais do seu idioma estarão implicados em AZ com regex.

Regex.IsMatch(email, @"^([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})(\]?)$", RegexOptions.ECMAScript)

1

Acabei usando esse regex, pois ele valida com êxito vírgulas, comentários, caracteres Unicode e endereços de domínio IP (v4).

Os endereços válidos serão:

"" @ example.org

(comentário) test@example.org

тест@example.org

Example @ example.org

teste @ [192.168.1.1]

 public const string REGEX_EMAIL = @"^(((\([\w!#$%&'*+\/=?^_`{|}~-]*\))?[^<>()[\]\\.,;:\s@\""]+(\.[^<>()[\]\\.,;:\s@\""]+)*)|(\"".+\""))(\([\w!#$%&'*+\/=?^_`{|}~-]*\))?@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$";

1

Um simples sem usar o Regex (que eu não gosto por sua baixa legibilidade):

bool IsValidEmail(string email)
{
    string emailTrimed = email.Trim();

    if (!string.IsNullOrEmpty(emailTrimed))
    {
        bool hasWhitespace = emailTrimed.Contains(" ");

        int indexOfAtSign = emailTrimed.LastIndexOf('@');

        if (indexOfAtSign > 0 && !hasWhitespace)
        {
            string afterAtSign = emailTrimed.Substring(indexOfAtSign + 1);

            int indexOfDotAfterAtSign = afterAtSign.LastIndexOf('.');

            if (indexOfDotAfterAtSign > 0 && afterAtSign.Substring(indexOfDotAfterAtSign).Length > 1)
                return true;
        }
    }

    return false;
}

Exemplos:

  • IsValidEmail("@b.com") // false
  • IsValidEmail("a@.com") // false
  • IsValidEmail("a@bcom") // false
  • IsValidEmail("a.b@com") // false
  • IsValidEmail("a@b.") // false
  • IsValidEmail("a b@c.com") // false
  • IsValidEmail("a@b c.com") // false
  • IsValidEmail("a@b.com") // true
  • IsValidEmail("a@b.c.com") // true
  • IsValidEmail("a+b@c.com") // true
  • IsValidEmail("a@123.45.67.89") // true

Ele deve ser simples e, portanto, não lida com casos raros, como emails com domínios entre colchetes que contêm espaços (normalmente permitidos), emails com endereços IPv6 etc.


1

Aqui está uma resposta para sua pergunta para você verificar.

using System;
using System.Globalization;
using System.Text.RegularExpressions;

public class RegexUtilities
{    
   public bool IsValidEmail(string strIn)
   {
       if (String.IsNullOrEmpty(strIn))
       {
          return false;

       }

       // Use IdnMapping class to convert Unicode domain names.

       try 
       {
          strIn = Regex.Replace(strIn, @"(@)(.+)$", this.DomainMapper, RegexOptions.None, TimeSpan.FromMilliseconds(200));

       }
       catch (RegexMatchTimeoutException) 
       {
           return false;

       }

       if (invalid)
       {
           return false;

       }

       // Return true if strIn is in valid e-mail format.    

       try 
       {
          return Regex.IsMatch(strIn, @"^(?("")("".+?(?<!\\)""@)|(([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, TimeSpan.FromMilliseconds(250));

       }
       catch (RegexMatchTimeoutException) 
       {
          return false;

       }

   }


   private string DomainMapper(Match match)
   {
      // IdnMapping class with default property values.

      IdnMapping idn = new IdnMapping();

      string domainName = match.Groups[2].Value;

      try 
      {
         domainName = idn.GetAscii(domainName);

      }
      catch (ArgumentException) 
      {
         invalid = true;

      }

      return match.Groups[1].Value + domainName;

   }

}

1

Com base na resposta do @Cogwheel, quero compartilhar uma solução modificada que funcione para o SSIS e o "Componente de script":

  1. Coloque o "Script Component" no seu Data Flow connect e abra-o.
  2. Na seção "Colunas de entrada", defina o campo que contém os endereços de email como "ReadWrite" (no exemplo 'fieldName').
  3. Volte para a seção "Script" e clique em "Editar script". Então você precisa esperar depois que o código for aberto.
  4. Coloque este código no método certo:

    public override void Input0_ProcessInputRow(Input0Buffer Row)
    {
        string email = Row.fieldName;
    
        try
        {
            System.Net.Mail.MailAddress addr = new System.Net.Mail.MailAddress(email);
            Row.fieldName= addr.Address.ToString();
        }
        catch
        {
            Row.fieldName = "WRONGADDRESS";
        }
    }

Em seguida, você pode usar uma divisão condicional para filtrar todos os registros inválidos ou o que você quiser fazer.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.