Codice C # per convalidare l'indirizzo e-mail


461

Qual è il codice più elegante per convalidare che una stringa è un indirizzo email valido?




ci sono molte altre validazioni importanti non solo la stringa, è meglio controllare se l'e-mail è presente su questo server smtp o l'utente sta inserendo qualsiasi e-mail .. ecc. o usare l'API che gestirà questo per essere sicuri che l'e-mail è corretto come ver-email.com
Amr Magdy,


Risposte:


784

Che dire di questo?

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

Per chiarire, la domanda è se una determinata stringa è una rappresentazione valida di un indirizzo e-mail, non se un indirizzo e-mail è una destinazione valida per inviare un messaggio. Per questo, l'unico vero modo è inviare un messaggio per confermare.

Si noti che gli indirizzi e-mail perdonano più di quanto si possa presumere. Queste sono tutte forme perfettamente valide:

  • COG @ ruota
  • "ruota dentata l'arancia" @ example.com
  • 123@$.xyz

Per la maggior parte dei casi d'uso, un falso "non valido" è molto peggio per gli utenti e le prove future rispetto a un falso "valido". Ecco un articolo che era la risposta accettata a questa domanda (da allora la risposta è stata cancellata). Ha molti più dettagli e alcune altre idee su come risolvere il problema.

Fornire controlli di integrità è ancora una buona idea per l'esperienza dell'utente. Supponendo che l'indirizzo e-mail sia valido, è possibile cercare domini di primo livello noti, controllare il dominio per un record MX, verificare errori di ortografia dai nomi di dominio comuni (gmail.cmo), ecc. Quindi presentare un avviso che fornisce all'utente un'opportunità per dire "sì, il mio server di posta consente davvero 🌮🍳🎁 come indirizzo e-mail".


Per quanto riguarda l'utilizzo della gestione delle eccezioni per la logica aziendale, sono d'accordo che è una cosa da evitare. Ma questo è uno di quei casi in cui la convenienza e la chiarezza possono superare il dogma.

Inoltre, se fai qualcos'altro con l'indirizzo e-mail, probabilmente si tratterà di trasformarlo in un indirizzo di posta. Anche se non usi questa funzione esatta, probabilmente vorrai usare lo stesso modello. È inoltre possibile verificare la presenza di tipi specifici di errore rilevando diverse eccezioni : formato null, vuoto o non valido.


Per il commento di Stuart, questo confronta l'indirizzo finale con la stringa originale invece di restituire sempre vero. MailAddress tenta di analizzare una stringa con spazi nelle porzioni "Nome visualizzato" e "Indirizzo", quindi la versione originale restituiva falsi positivi.


--- Ulteriori letture ---

Documentazione per System.Net.Mail.MailAddress

Spiegazione di ciò che costituisce un indirizzo email valido


23
In realtà, non è sbagliato. a @ a è un indirizzo e-mail valido. Vedi haacked.com/archive/2007/08/21/… In realtà, questo metodo restituisce risultati errati se si utilizza un indirizzo tra virgolette.
Ruota dentata

53
+1: Questa è la risposta migliore se stai usando le System.Net.Mailclassi per inviare la posta, cosa che probabilmente sei se stai usando .NET. Abbiamo deciso di utilizzare questo tipo di convalida semplicemente perché non ha senso accettare indirizzi e-mail, anche validi, a cui non è possibile inviare posta.
Greg Beech,

24
Non lo consiglio. Restituisce vero:IsValidEmail("this is not valid@email$com");
Kakashi l'

15
Molti problemi sembrano essere dovuti al fatto che MailAddress tenta di analizzare anche DisplayName, quindi "single space@domain.com" analizza DisplayName "single" e indirizzo "space@domain.com". Una soluzione per questo è: return (addr.Address == email);
Stuart,

18
Mi piace questo; Non capisco che la compulsione sia più restrittiva delle specifiche reali. I falsi negativi sono molto peggio dei falsi positivi ("cosa intendi dire la mia e-mail non è valida? ")
Casey,

242

Questa è una vecchia domanda, ma tutte le risposte che ho trovato su SO, comprese quelle più recenti, hanno una risposta simile a questa. Tuttavia, in .Net 4.5 / MVC 4 è possibile aggiungere la convalida dell'indirizzo e-mail a un modulo aggiungendo l'annotazione [EmailAddress] da System.ComponentModel.DataAnnotations, quindi mi chiedevo perché non potevo semplicemente utilizzare la funzionalità integrata da. Net in generale.

Questo sembra funzionare e mi sembra abbastanza 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
Fantastico, anche se è deludente che gli Stati membri non possano concordare con la propria documentazione . Ciò rifiuta js@proseware.com9
Casey il

13
Si noti che EmailAddressAttributeè meno permissivo di System.Net.Mail.MailAddress- ad esempio, MailAddressaccetta un indirizzo per un TLD. Solo qualcosa da tenere a mente se devi essere il più permissivo possibile.
Aaronino

5
@Cogwheel: se la risposta si trova da qualche parte nei commenti, probabilmente dovrebbe essere aggiunta al corpo principale della risposta.
hofnarwillie,

6
@hofnarwillie: è nel corpo principale, ma i commenti sono elaborati. Se il tuo obiettivo non è far arrabbiare i tuoi utenti, la tua convalida non dovrebbe essere più restrittiva delle specifiche. L'unico modo per verificare veramente se un'e-mail è valida è inviare un messaggio di prova.
Ruota dentata

4
Si prega di notare che foo.IsValid(null);ritorna true.
urig,

62

Uso questo metodo a linea singola che fa il lavoro per me-

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

Secondo i commenti, questo "fallirà" se source(l'indirizzo e-mail) è nullo.

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

1
Questo non funziona per me; Ottengo "Non esistono" Annotazioni di dati "... manca un riferimento all'assembly?" Quale riferimento devo aggiungere?
B. Clay Shannon,

Questo restituirà vero se l'origine è nulla. Vedere msdn.microsoft.com/en-us/library/hh192424 "true se il valore specificato è valido o null; altrimenti, false."
jao,

2
Una versione migliore:public static Boolean IsValidMailAddress(this String pThis) => pThis == null ? false : new EmailAddressAttribute().IsValid(pThis);
Sebastian Hofmann

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

1
Non credo che questo metodo di estensione dovrebbe restituire silenziosamente falsestringhe null. È per questo che propongono la (meglio ancora meglio) ++ versione: public static bool IsValidEmailAddress(this string address) => new EmailAddressAttribute().IsValid(address ?? throw new ArgumentNullException());. Ora vado e ho trovato la Chiesa Riformata dei Versionists Better Better Better.
Marc

41

.net 4.5 ha aggiunto System.ComponentModel.DataAnnotations.EmailAddressAttribute

Puoi sfogliare l'origine EmailAddressAttribute , questo è il Regex che utilizza 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
Purtroppo EmaillAddressAttribute consente Ñ che non è un carattere valido per l'e
BZ

16
@BZ Sì, lo è. Perché pensi che non lo sia?
Casey,

@Chad Grant: questa è una versione C #. Potete per favore fornirne uno VB.Net. Perché ciò sfuggirà ai caratteri come \\ a \ o puoi fornire una stringa alla lettera.
Nikhil Agrawal,

3
Funziona, ma non dimenticare RegexOptions.IgnoreCaseperché questo modello non consente esplicitamente le lettere maiuscole!
Chris,

1
Si noti che Regex è molto deliberato: "Questo attributo fornisce una convalida della posta elettronica sul lato server equivalente a jquery validate e quindi condivide la stessa espressione regolare".
Ohad Schneider,

38

Ho preso la risposta di Phil dal n. 1 e ho creato questa lezione. Chiamalo così:bool isValid = Validator.EmailIsValid(emailString);

Ecco la 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
Solo una piccola, ma vorrei usare: return (! String.IsNullOrEmpty (emailAddress)) && ValidEmailRegex.IsMatch (emailAddress);
Marc,

Questo è solo orrore :)
Alexandru Dicu,

31

Personalmente, direi che dovresti solo assicurarti che ci sia un simbolo @, con possibilmente un. carattere. Ci sono molte regex che potresti usare di varia correttezza, ma penso che la maggior parte di questi tralasci indirizzi e-mail validi o li lasci passare non validi. Se le persone vogliono inserire un indirizzo e-mail falso, ne inseriranno uno falso. Se è necessario verificare che l'indirizzo di posta elettronica sia legittimo e che la persona abbia il controllo di tale indirizzo di posta elettronica, è necessario inviare loro un'e-mail con un collegamento codificato speciale in modo che possano verificare che si tratti effettivamente di un indirizzo reale.


6
Personalmente penso che dovresti fare un po 'più di validazione di così. Qualcuno è tenuto a provare l'indirizzo e-mail di Bobby Table o peggio.
Luke Quinane,

31
Cosa c'è di sbagliato nell'indirizzo e-mail di bobby table se stai usando dichiarazioni preparate. Stiamo parlando di indirizzi e-mail validi, non di altre cose che non hanno nulla a che fare con ciò che costituisce un indirizzo e-mail valido, come come eseguire correttamente le query SQL in modo da non avere problemi di iniezione SQL.
Kibbee,

Immagino che tu non sappia cosa ci metterà qualcuno, ma una persona maliziosa sa che il valore potrebbe eventualmente essere inserito nel tuo sistema di posta. Preferirei approfondire la difesa ed essere un po 'più severo.
Luke Quinane,

10
Questo è per il sistema di posta di cui preoccuparsi. Non andrei in giro a rifiutare indirizzi e-mail perfettamente validi solo perché potrebbe essere un problema di sicurezza con qualche altro sistema. Se tutto il tuo server di posta elettronica ha bisogno di un indirizzo e-mail non valido per causare problemi di sicurezza, dovresti probabilmente passare a un altro server.
Kibbee,

4
La difesa in profondità funziona solo se ogni livello della tua cipolla di sicurezza non è marcio. Uno strato marcio significa rovinare l'intera cipolla. Rifiutare "foo@example.com.au" perché vuoi difenderti dalle vulnerabilità nella codifica della legge µ di Sun non ha senso, vero? Non ridere, mi è successo. Il motivo per cui sto commentando è che Medicare Australia non consente indirizzi ".au", ma solo ".com". Leggi anche Mark Swanson, "Come non convalidare la posta elettronica", mdswanson.com/blog/2013/10/14/…
ManicDee,

17

Penso che il modo migliore sia il seguente:

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

Puoi avere questa funzione statica in una classe generale.


Questa risposta non accetta un indirizzo con un TLD nella parte dominio.
Simone,

15

Codice breve 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
Grazie per la soluzione
Jack Gajanan,

Ho dovuto cambiare il bool statico pubblico IsValidEmail (questa e-mail stringa) in bool statico pubblico IsValidEmail (e-mail stringa) per evitare QUESTO: stackoverflow.com/questions/10412233/…
Goner Doug

@Goner Doug, questa funzionalità funzionerà in questo modo. (Bool flag = EmailAddress.IsValidEmail ())
Naveen

2
"QUESTO" doveva essere rimosso per evitare di causare problemi al compilatore quando aggiunto al mio modulo.
Goner Doug,

@Goner Doug, la sua funzionalità funzionerà in questo modo. string email = "abc@xyz.com"; if (email.IsValidEmail ()) {return false; } else {return true;}
Naveen,

14

Il modo più elegante è usare i metodi integrati di .Net.

Questi metodi:

  • Sono provati e testati. Questi metodi sono utilizzati nei miei progetti professionali.

  • Usa le espressioni regolari internamente, che sono affidabili e veloci.

  • Realizzato da Microsoft per C #. Non è necessario reinventare la ruota.

  • Restituisce un risultato bool. True indica che l'e-mail è valida.

Per utenti di .Net 4.5 e versioni successive

Aggiungi questo riferimento al tuo progetto:

System.ComponentModel.DataAnnotations

Ora puoi usare il seguente codice:

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

Esempio di utilizzo

Ecco alcuni metodi per dichiarare:

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 codice dimostrandoli in azione:

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());

}

Inoltre, questo esempio:

  • Si estende oltre le specifiche poiché una singola stringa viene utilizzata per contenere 0, uno o più indirizzi e-mail sperati da un punto e virgola ; .
  • Dimostra chiaramente come utilizzare il metodo IsValid dell'oggetto EmailAddressAttribute.

Alternativa, per gli utenti di una versione di .Net inferiore a 4.5

Per situazioni in cui .Net 4.5 non è disponibile, utilizzo la seguente soluzione:

In particolare, utilizzo:

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 Non ho visto una risposta EmailAddressAttribute e nessuna risposta che utilizza il nuovo MailAddress () con un controllo sull'input == .Address quindi penso che sia abbastanza utile. Senza leggere i commenti la risposta accettata è piuttosto sbagliata. nuovo MailAddress ("Foobar Some@thing.com") lo dimostra.
Jan

@Jan prima, Manik ha battuto Knickerless di EmailAddressAttributepoco meno di quattro mesi, anche se questo risolve il nullproblema.
ruffin,

7

Ad essere onesti, nel codice di produzione, il meglio che faccio è controllare un @simbolo.

Non sono mai in grado di convalidare completamente le e-mail. Sai come vedo se fosse davvero valido? Se è stato inviato. Se così non fosse, è male, se così fosse, la vita va bene. Questo è tutto ciò che devo sapere.


6

Trovo che questa regex sia un buon compromesso tra la ricerca di qualcosa di più del semplice segno @ e l'accettazione di strani casi limite:

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

Almeno ti farà mettere qualcosa intorno al segno @ e almeno un dominio dall'aspetto normale.


Mi è venuta in mente la stessa regex;) Tuttavia consente caratteri non validi
Stefan

Questa risposta non accetta un TLD nella parte dominio.
Simone,

@Simone probabilmente nessuno ha indirizzi e-mail con il TLD nella parte del dominio anche se in pratica: serverfault.com/a/721929/167961 nota nei commenti potrebbe essere vietato in questi giorni
Matthew Lock

@MatthewLock Potrebbe essere un indirizzo intranet? Come bob@companyinternal?
Simone,

@Simone qualcuno nella vita reale utilizza effettivamente questo schema?
Matthew Lock,

4

La convalida dell'indirizzo e-mail non è così semplice come potrebbe sembrare. In realtà è teoricamente impossibile convalidare completamente un indirizzo e-mail usando solo un'espressione regolare.

Dai un'occhiata al mio post sul blog per una discussione sull'argomento e un'implementazione di F # usando FParsec. [/ shameless_plug]


1
Mi è piaciuto il tuo elenco di approcci alternativi; molto interessante.
Luke Quinane,

1
Articolo interessante. Ma seriamente chi sta inserendo commenti, e quelli nidificati, negli indirizzi e-mail?
Matthew Lock,

3
@matthew Non so perché l'IETF lo abbia nemmeno permesso, ma è possibile , quindi una validazione approfondita deve tenerne conto.
Mauricio Scheffer,

4

Ecco la mia risposta: la soluzione di Phil fallisce per i domini a lettera singola come "someone@q.com". Che ci crediate o no, è usato =) (va a centurylink, per esempio).

La risposta di Phil funzionerà anche solo con lo standard PCRE ... quindi C # la prenderà, ma javascript sta per bombardare. È troppo complesso per javascript. Quindi non puoi usare la soluzione di Phil per gli attributi di validazione mvc.

Ecco la mia regex. Funzionerà perfettamente con gli attributi di convalida MVC.
- Tutto prima di @ è semplificato, in modo che almeno javascript funzioni. Sto bene rilassando la convalida qui a condizione che Exchange Server non mi dia un 5.1.3. - Tutto ciò che segue @ è la soluzione di Phil modificata per i domini a lettera singola.

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]$";

Per le persone che suggeriscono di utilizzare System.net.mail MailMessage (), quella cosa è MODO flessibile. Certo, C # accetterà l'e-mail, ma poi Exchange Server bombarderà con errore di runtime 5.1.3 non appena si tenta di inviare l'e-mail.


quella sembra essere la migliore risposta più ponderata / ragionevole / reale, grazie Ralph!
Fattie,

questa è la risposta migliore finora! Non posso credere che una cattiva soluzione che accetta basket@ballcome indirizzo di posta elettronica valido abbia ottenuto la risposta corretta e tutti questi voti. Grazie comunque!
disasterkid,

Grazie, questa è la soluzione migliore e dovrebbe essere accettata la risposta.
Bat_Programmer,

3

Se tu e davvero intendiamo davvero sapere se un indirizzo e-mail è valido ... chiedi allo scambiatore di posta di provarlo, non è necessaria alcuna regex. Posso fornire il codice se richiesto.

I passaggi generali sono i seguenti: 1. l'indirizzo e-mail ha una parte del nome di dominio? (indice di @> 0) 2. usando una query DNS chiedi se il dominio ha uno scambiatore di posta 3. apri la connessione tcp allo scambiatore di posta 4. usando il protocollo smtp, apri un messaggio al server usando l'indirizzo e-mail come ricevitore 5. analizzare la risposta del server. 6. abbandonare il messaggio se lo hai fatto fino a questo punto, tutto va bene.

Questo è come puoi immaginare, molto costoso in termini di tempo e si basa su smtp, ma funziona.


Hai creato falsi, matrici e / o beffe per quelle interfacce?
Segna A

1
Non funzionerà Il protocollo smtp per verificare un indirizzo e-mail è stato a lungo deprecato / non utilizzato. È considerata una cattiva pratica abilitarlo sui server di posta poiché gli spammer utilizzano tale funzionalità.
Chad Grant,

Terrò il tuo suggerimento fino al punto 2. Molto più a prova di futuro rispetto alla ricerca di un modello di nome di dominio noto.
Simone,

Nitpicking, ma definire "ha uno scambiatore di posta" ? Se non esiste alcun record MX, SMTP deve tornare al record A / AAAA, come da RFC2821 / 5321. Se esiste un record MX, potrebbe non indicare che esiste uno scambiatore di posta (RFC7505). Davvero, l'unico modo è inviare loro una mail con un link di invito all'azione e aspettare che rispondano ...
jimbobmcgee

2

In generale, un'espressione regolare per convalidare gli indirizzi e-mail non è una cosa facile da inventare; al momento in cui scrivo, la sintassi di un indirizzo e-mail deve seguire un numero relativamente elevato di standard e implementarli tutti in un'espressione regolare è praticamente impossibile!

Consiglio vivamente di provare il nostro EmailVerify.NET , una libreria .NET matura che può convalidare gli indirizzi e-mail seguendo tutti gli standard IETF attuali (RFC 1123, RFC 2821, RFC 2822, RFC 3696, RFC 4291, RFC 5321 e RFC 5322) , verifica i relativi record DNS, verifica se le cassette postali di destinazione possono accettare messaggi e possono persino stabilire se un determinato indirizzo è usa e getta o meno.

Disclaimer: sono lo sviluppatore principale di questo componente.


Degno di nota! "Successivamente, tenta di contattare lo scambiatore di posta responsabile per l'indirizzo di posta elettronica specificato e avvia una finta finestra di dialogo SMTP con quel server, emulando un vero server di posta. In questo modo si assicura che il server possa gestire le e-mail per l'indirizzo. Molti server SMTP in realtà restituire risposte false positive come protezione contro gli spammer: per ovviare a questo problema, EmailVerify per .NET tenta finalmente di interrogare più volte lo scambiatore di posta di destinazione con indirizzi diversi ".
Matthew Lock,

Grazie, @MatthewLock;)
Efran Cobisi,

Bello, ma vedo solo edizioni a pagamento. Qualche piano per una community / OpenSource?
Ohad Schneider,

1
@OhadSchneider Sì: stiamo offrendo una versione gratuita della nostra tecnologia di convalida della posta elettronica tramite Verifalia, il nostro servizio di verifica della posta elettronica SaaS . Verifalia viene fornito con SDK gratuiti e open source per le principali piattaforme di sviluppo software, incluso .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;
        }

Non verrà convalidato a@b.info come indirizzo e-mail valido.
Ray Cheng,

2

Nel caso in cui stai usando FluentValidation potresti scrivere qualcosa di così semplice:

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

una piccola modifica alla risposta di @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;
  }
}

Questo non sembra aiutare ... Console.WriteLine(MailAddress("asdf@asdf.").Address);genera "asdf @ asdf.", Che non è valido.
Langdon,

.net sembra avere una propria definizione di valido. discussione
waitforit

2

Ci sono molte risposte forti qui. Tuttavia, raccomando di fare un passo indietro. @Cogwheel risponde alla domanda https://stackoverflow.com/a/1374644/388267 . Tuttavia, potrebbe essere costoso in uno scenario di convalida in blocco, se molti degli indirizzi e-mail in fase di convalida non sono validi. Suggerisco di usare un po 'di logica prima di entrare nel suo blocco try-catch. So che il seguente codice potrebbe essere scritto usando RegEx ma potrebbe essere costoso da capire per i nuovi sviluppatori. Questo vale il mio twopence:

    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

La risposta più votata da @Cogwheel è la risposta migliore, tuttavia ho cercato di implementare il trim()metodo stringa in modo da tagliare tutto lo spazio bianco dell'utente dall'inizio alla fine della stringa. Controlla il codice qui sotto per un esempio completo-

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

Il rischio è che stai convalidando un indirizzo e-mail diverso rispetto alla fonte, lasciandoti a pensare di poter spedire alla versione (in questo caso) non ritagliata dell'indirizzo e-mail specificato. Un approccio migliore sarebbe quello di creare un metodo separato SanitizeEmail(string email), utilizzando il risultato di tale metodo per convalidare e inviare l'e-mail.
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

Verifica che la stringa di posta elettronica sia nel formato giusto o nel formato sbagliato 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

/ Utilizzo del Regex interno utilizzato nella creazione del "nuovo EmailAddressAttribute ();" componente in .Net4.5 >>> utilizzando System.ComponentModel.DataAnnotations; // Per convalidare un indirizzo e-mail ...... Testato e funzionante.

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

Inoltre, puoi usare questo:

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


dice vero per questa email: "fulya_42_@hotmail.coö" e genera un errore a mandrill api
MonsterMMORPG,

1
Innanzitutto, l'e-mail è valida wrt esempio@esempio.co o esempio@esempio.com .... L'e-mail ha tutte le stringhe e i criteri validi tranne l'ultimo carattere "ö" e puoi facilmente aggiungere una semplice condizione per convalidare tale carattere . In secondo luogo, non sono sicuro di quell'errore api mandrill, potresti voler verificare il tuo metodo di utilizzo perché ho usato questa convalida su qualche altro ambiente / api ed è stato buono con me.
Aina Ademola C,

1

Ho semplificato la risposta di Poyson 1 in questo modo:

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

Il modo semplice per identificare l'emailid è valido o meno.

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

C'è un problema di cultura in regex in C # piuttosto che in js. Quindi dobbiamo usare regex in modalità USA per il controllo della posta elettronica. Se non usi la modalità ECMAScript, i caratteri speciali della tua lingua sono impliciti in AZ con 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

Ho finito per usare questo regex, poiché convalida con successo virgole, commenti, caratteri Unicode e indirizzi di dominio IP (v4).

Gli indirizzi validi saranno:

"" @ example.org

(comment)test@example.org

тест@example.org

ტესტი @ example.org

test @ [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

Un semplice senza usare Regex (che non mi piace per la sua scarsa leggibilità):

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

Esempi:

  • 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

È pensato per essere semplice e quindi non tratta casi rari come e-mail con domini tra parentesi che contengono spazi (in genere consentiti), e-mail con indirizzi IPv6, ecc.


1

Ecco una risposta alla tua domanda da verificare.

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

Sulla base della risposta di @Cogwheel, voglio condividere una soluzione modificata che funziona per SSIS e il "Componente di script":

  1. Posiziona il "Componente script" nella connessione al flusso di dati, quindi aprilo.
  2. Nella sezione "Colonne di input" impostare il campo che contiene gli indirizzi e-mail su "ReadWrite" (nell'esempio "fieldName").
  3. Torna alla sezione "Script" e fai clic su "Modifica script". Quindi è necessario attendere dopo l'apertura del codice.
  4. Inserisci questo codice nel metodo giusto:

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

Quindi puoi utilizzare una suddivisione condizionale per filtrare tutti i record non validi o qualunque cosa tu voglia fare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.