C # -Code zum Überprüfen der E-Mail-Adresse


461

Was ist der eleganteste Code, um zu überprüfen, ob eine Zeichenfolge eine gültige E-Mail-Adresse ist?



9
Werfen Sie einen Blick auf Phil Haacks Artikel: " Ich wusste, wie man eine E-Mail-Adresse validiert, bis ich den RFC lese "
Luke Quinane

Es gibt viele andere wichtige Überprüfungen, nicht nur die Zeichenfolge. Es ist besser zu überprüfen, ob die E-Mail auf diesem SMTP-Server vorhanden ist oder der Benutzer eine E-Mail eingibt ist korrekt wie ver-email.com
Amr Magdy


Sie können die Bibliothek github.com/jstedfast/EmailValidation verwenden.
Mohammad Reza Sadreddini

Antworten:


784

Was ist damit?

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

Zur Verdeutlichung wird die Frage gestellt, ob eine bestimmte Zeichenfolge eine gültige Darstellung einer E-Mail-Adresse ist und nicht, ob eine E-Mail-Adresse ein gültiges Ziel zum Senden einer Nachricht ist. Der einzige wirkliche Weg besteht darin, eine Nachricht zur Bestätigung zu senden.

Beachten Sie, dass E-Mail-Adressen verzeihender sind, als Sie zunächst annehmen könnten. Dies sind alles vollkommen gültige Formen:

  • Zahnrad
  • "Zahnrad die Orange" @ example.com
  • 123@$.xyz

In den meisten Anwendungsfällen ist ein falsches "ungültig" für Ihre Benutzer und die Zukunftssicherung viel schlechter als ein falsches "gültig". Hier ist ein Artikel, der früher die akzeptierte Antwort auf diese Frage war (diese Antwort wurde inzwischen gelöscht). Es enthält viel mehr Details und einige andere Ideen zur Lösung des Problems.

Die Bereitstellung von Sanity Checks ist immer noch eine gute Idee für die Benutzererfahrung. Angenommen, die E-Mail-Adresse ist gültig, können Sie nach bekannten Domains der obersten Ebene suchen, die Domain auf einen MX-Eintrag überprüfen, nach Rechtschreibfehlern bei allgemeinen Domainnamen (gmail.cmo) suchen usw. Anschließend eine Warnung an den Benutzer senden eine Chance zu sagen "Ja, mein Mailserver erlaubt wirklich 🌮🍳🎁 als E-Mail-Adresse."


Ich stimme zu, dass die Verwendung der Ausnahmebehandlung für die Geschäftslogik vermieden werden sollte. Dies ist jedoch einer der Fälle, in denen die Bequemlichkeit und Klarheit das Dogma überwiegen kann.

Wenn Sie mit der E-Mail-Adresse etwas anderes tun, müssen Sie sie wahrscheinlich in eine Mail-Adresse umwandeln. Auch wenn Sie nicht genau diese Funktion verwenden, möchten Sie wahrscheinlich dasselbe Muster verwenden. Sie können auch nach bestimmten Arten von Fehlern suchen, indem Sie verschiedene Ausnahmen abfangen: null, leer oder ungültiges Format.


Laut Stuarts Kommentar vergleicht dies die endgültige Adresse mit der ursprünglichen Zeichenfolge, anstatt immer true zurückzugeben. MailAddress versucht, eine Zeichenfolge mit Leerzeichen in die Bereiche "Anzeigename" und "Adresse" zu analysieren, sodass die ursprüngliche Version falsch positive Ergebnisse zurückgibt.


--- Weiterführende Literatur ---

Dokumentation für System.Net.Mail.MailAddress

Erläuterung, woraus eine gültige E-Mail-Adresse besteht


23
Eigentlich ist das nicht falsch. a @ a ist eine gültige E-Mail-Adresse. Siehe haacked.com/archive/2007/08/21/… Tatsächlich gibt diese Methode falsche Ergebnisse zurück, wenn Sie eine Adresse mit Anführungszeichen verwenden.
Zahnrad

53
+1: Dies ist die beste Antwort, wenn Sie die System.Net.MailKlassen zum Senden von E-Mails verwenden. Dies ist wahrscheinlich der Fall, wenn Sie .NET verwenden. Wir haben uns für diese Art der Validierung entschieden, weil es keinen Sinn macht, E-Mail-Adressen zu akzeptieren - auch gültige -, an die wir keine E-Mails senden können.
Greg Beech

24
Ich empfehle nicht. Es gibt wahr zurück:IsValidEmail("this is not valid@email$com");
Kakashi

15
Viele der Probleme scheinen darauf zurückzuführen zu sein, dass MailAddress versucht, den DisplayName ebenfalls zu analysieren. Daher wird "single space@domain.com" in DisplayName "single" und Adresse "space@domain.com" analysiert. Eine Lösung hierfür ist: return (addr.Address == email);
Stuart

18
Ich mag das; Ich bekomme nicht den Zwang, restriktiver zu sein als die tatsächliche Spezifikation. Falsche Negative sind viel schlimmer als falsche Positive ("Was meinst du damit, dass meine E-Mail ungültig ist? ")
Casey

242

Dies ist eine alte Frage, aber alle Antworten, die ich auf SO gefunden habe, einschließlich neuerer, werden ähnlich wie diese beantwortet. In .Net 4.5 / MVC 4 können Sie einem Formular jedoch eine E-Mail-Adressüberprüfung hinzufügen, indem Sie die Anmerkung [EmailAddress] aus System.ComponentModel.DataAnnotations hinzufügen. Daher habe ich mich gefragt, warum ich die integrierte Funktionalität von nicht einfach verwenden kann. Netto im Allgemeinen.

Dies scheint zu funktionieren und scheint mir ziemlich elegant zu sein:

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
Cool, obwohl es enttäuschend ist, dass MS dies nicht mit ihrer eigenen Dokumentation vereinbaren kann . Dies lehnt js@proseware.com9
Casey

13
Beachten Sie, dass dies EmailAddressAttributeweniger zulässig ist als System.Net.Mail.MailAddressbeispielsweise MailAddresseine Adresse für eine TLD akzeptiert. Nur etwas zu beachten, wenn Sie so freizügig wie möglich sein müssen.
Aaroninus

5
@Cogwheel: Wenn die Antwort irgendwo in den Kommentaren liegt, sollte sie wahrscheinlich zum Hauptteil der Antwort hinzugefügt werden.
Hofnarwillie

6
@hofnarwillie: es ist im Hauptteil, aber die Kommentare ausführlich. Wenn Ihr Ziel darin besteht, Ihre Benutzer nicht zu verärgern, sollte Ihre Validierung nicht restriktiver sein als die Spezifikation. Die einzige Möglichkeit, wirklich zu überprüfen, ob eine E-Mail gültig ist, besteht darin, eine Testnachricht zu senden.
Zahnrad

4
Bitte beachten Sie, dass foo.IsValid(null);zurückkehrt true.
Urig

62

Ich benutze diese Single-Liner-Methode, die die Arbeit für mich erledigt.

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

Gemäß den Kommentaren wird dies "fehlschlagen", wenn die source(die E-Mail-Adresse) null ist.

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

1
Das funktioniert bei mir nicht; Ich erhalte die Meldung "Datenanmerkungen" sind nicht vorhanden. Fehlt Ihnen eine Baugruppenreferenz? " Welche Referenz muss ich hinzufügen?
B. Clay Shannon

Dies gibt true zurück, wenn source null ist. Siehe msdn.microsoft.com/en-us/library/hh192424 "true, wenn der angegebene Wert gültig oder null ist; andernfalls false."
Jao

2
Eine bessere Version:public static Boolean IsValidMailAddress(this String pThis) => pThis == null ? false : new EmailAddressAttribute().IsValid(pThis);
Sebastian Hofmann

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

1
Ich denke nicht, dass diese Erweiterungsmethode stillschweigend falsefür Nullzeichenfolgen zurückgegeben werden sollte. Deshalb schlage ich die (noch besser bessere) ++ Version vor : public static bool IsValidEmailAddress(this string address) => new EmailAddressAttribute().IsValid(address ?? throw new ArgumentNullException());. Ich werde jetzt die reformierte Kirche der noch besseren, besseren Versionisten gründen.
März 2377

41

.net 4.5 System.ComponentModel.DataAnnotations.EmailAddressAttribute hinzugefügt

Sie können die Quelle von EmailAddressAttribute durchsuchen. Dies ist der Regex, der intern verwendet wird:

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
Leider erlaubt das EmaillAddressAttribute Ñ, was kein gültiges Zeichen für E-Mail ist
BZ

16
@BZ Ja, das ist es. Warum denkst du, ist es nicht?
Casey

@Chad Grant: Dies ist eine C # -Version. Können Sie bitte ein VB.Net zur Verfügung stellen? Denn das entgeht Zeichen wie \\ bis \ oder Sie können eine wörtliche Zeichenfolge angeben.
Nikhil Agrawal

3
Dies funktioniert, aber vergessen Sie nicht, RegexOptions.IgnoreCaseda dieses Muster keine expliziten Großbuchstaben zulässt!
Chris

1
Beachten Sie, dass Regex sehr bewusst ist: "Dieses Attribut bietet eine serverseitige E-Mail-Validierung, die der jquery-Validierung entspricht, und verwendet daher denselben regulären Ausdruck."
Ohad Schneider

38

Ich habe Phils Antwort von # 1 genommen und diese Klasse erstellt. Nennen Sie es so:bool isValid = Validator.EmailIsValid(emailString);

Hier ist die Klasse:

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
Nur eine kleine, aber ich würde verwenden: return (! String.IsNullOrEmpty (emailAddress)) && ValidEmailRegex.IsMatch (emailAddress);
Marc

Dies ist nur Horror :)
Alexandru Dicu

31

Persönlich würde ich sagen, dass Sie nur sicherstellen sollten, dass sich dort ein @ -Symbol befindet, möglicherweise mit einem. Charakter. Es gibt viele reguläre Ausdrücke, die Sie mit unterschiedlicher Korrektheit verwenden können, aber ich denke, die meisten davon lassen gültige E-Mail-Adressen aus oder lassen ungültige durch. Wenn Leute eine gefälschte E-Mail-Adresse eingeben möchten, geben sie eine gefälschte ein. Wenn Sie überprüfen müssen, ob die E-Mail-Adresse legitim ist und ob die Person die Kontrolle über diese E-Mail-Adresse hat, müssen Sie ihnen eine E-Mail mit einem speziellen codierten Link senden, damit sie überprüfen können, ob es sich tatsächlich um eine echte Adresse handelt.


6
Ich persönlich denke, Sie sollten ein bisschen mehr Validierung als das tun. Jemand muss die E-Mail-Adresse von Bobby Table oder noch schlimmer versuchen.
Luke Quinane

31
Was stimmt nicht mit der E-Mail-Adresse von Bobby Table, wenn Sie vorbereitete Anweisungen verwenden? Es handelt sich um gültige E-Mail-Adressen, nicht um andere Dinge, die nichts mit einer gültigen E-Mail-Adresse zu tun haben, z. B. die ordnungsgemäße Ausführung von SQL-Abfragen, damit keine Probleme mit der SQL-Injektion auftreten.
Kibbee

Ich denke, Sie wissen nicht, was jemand dort eingeben wird, aber eine böswillige Person weiß, dass der Wert möglicherweise in Ihr Mailsystem eingespeist wird. Ich würde es einfach vorziehen, mich eingehend zu verteidigen und etwas strenger zu sein.
Luke Quinane

10
Das ist etwas, worüber sich das Mailsystem Sorgen machen muss. Ich würde nicht darum herumgehen, perfekt gültige E-Mail-Adressen abzulehnen, nur weil dies ein Sicherheitsproblem mit einem anderen System sein könnte. Wenn Ihr E-Mail-Server lediglich eine fehlerhafte E-Mail-Adresse benötigt, um Sicherheitsprobleme zu verursachen, sollten Sie wahrscheinlich zu einem anderen Server wechseln.
Kibbee

4
Tiefenverteidigung funktioniert nur, wenn jede Stufe Ihrer Sicherheitszwiebel nicht faul ist. Eine faule Schicht bedeutet, dass Sie die ganze Zwiebel verderben. Das Ablehnen von "foo@example.com.au", weil Sie sich gegen Schwachstellen in der µ-Law-Codierung von Sun verteidigen möchten, ist nicht sinnvoll, oder? Lach nicht, es ist mir passiert. Der Grund, warum ich hier kommentiere, ist, dass Medicare Australia keine ".au" -Adressen zulässt, sondern nur ".com". Lesen Sie auch Mark Swanson, "Wie man E-Mails nicht validiert", mdswanson.com/blog/2013/10/14/…
ManicDee

17

Ich denke, der beste Weg ist wie folgt:

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

Sie können diese statische Funktion in einer allgemeinen Klasse haben.


Diese Antwort akzeptiert keine Adresse mit einer TLD im Domänenteil.
Simone

15

Kurzer und genauer Code

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
Vielen Dank für die Lösung
Jack Gajanan

Ich musste den öffentlichen statischen Bool IsValidEmail (diese String-E-Mail) in den öffentlichen statischen Bool IsValidEmail (String-E-Mail) ändern
Goner Doug

@Goner Doug, diese Funktion wird so funktionieren. (Bool flag = EmailAddress.IsValidEmail ())
Naveen

2
Das "DIESE" musste entfernt werden, um Compilerprobleme beim Hinzufügen zu meinem Formular zu vermeiden.
Goner Doug

@Goner Doug, seine Funktionalität wird so funktionieren. Zeichenfolge email = "abc@xyz.com"; if (email.IsValidEmail ()) {return false; } else {return true;}
Naveen

14

Am elegantesten ist es, die in .Net integrierten Methoden zu verwenden.

Diese Methoden:

  • Sind bewährt. Diese Methoden werden in meinen eigenen beruflichen Projekten verwendet.

  • Verwenden Sie intern reguläre Ausdrücke, die zuverlässig und schnell sind.

  • Hergestellt von Microsoft für C #. Das Rad muss nicht neu erfunden werden.

  • Gibt ein Bool-Ergebnis zurück. True bedeutet, dass die E-Mail gültig ist.

Für Benutzer von .Net 4.5 und höher

Fügen Sie diese Referenz Ihrem Projekt hinzu:

System.ComponentModel.DataAnnotations

Jetzt können Sie den folgenden Code verwenden:

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

Anwendungsbeispiel

Hier sind einige Methoden zum Deklarieren:

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;

}

... und Code, der sie in Aktion demonstriert:

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

}

Außerdem dieses Beispiel:

  • Erweitert die Spezifikation, da eine einzelne Zeichenfolge 0, eine oder mehrere E-Mail-Adressen enthält, die durch ein Semikolon getrennt sind ;.
  • Zeigt deutlich, wie die IsValid-Methode des EmailAddressAttribute-Objekts verwendet wird.

Alternative für Benutzer einer Version von .Net unter 4.5

In Situationen, in denen .Net 4.5 nicht verfügbar ist, verwende ich die folgende Lösung:

Insbesondere benutze ich:

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 Ich habe keine EmailAddressAttribute-Antwort gesehen und keine Antwort, die neue MailAddress () mit einer Überprüfung der Eingabe == .Address verwendet, daher finde ich sie ziemlich nützlich. Ohne Kommentare zu lesen, ist die akzeptierte Antwort ziemlich falsch. Die neue MailAddress ("Foobar Some@thing.com") beweist dies.
Jan

@ Jan fwiw, Manik schlug Knickerless EmailAddressAttributeum knapp vier Monate, obwohl dieser das nullProblem auffängt .
Ruffin

7

Um ehrlich zu sein, suche ich im Produktionscode am besten nach einem @Symbol.

Ich bin nie in der Lage, E-Mails vollständig zu validieren. Sie wissen, wie ich sehe, ob es wirklich gültig war? Wenn es gesendet wurde. Wenn nicht, ist es schlecht, wenn ja, ist das Leben gut. Das ist alles was ich wissen muss.


6

Ich finde, dass dieser reguläre Ausdruck ein guter Kompromiss zwischen der Suche nach mehr als nur der @ -Marke und dem Akzeptieren seltsamer Randfälle ist:

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

Es wird Sie zumindest dazu bringen, etwas um die @ -Marke zu setzen und zumindest eine normal aussehende Domain.


Ich habe mir den gleichen regulären Ausdruck ausgedacht;) Es erlaubt jedoch ungültige Zeichen
Stefan

Diese Antwort akzeptiert keine TLD im Domänenteil.
Simone

@ Simone wahrscheinlich hat niemand E-Mail-Adressen mit der TLD im Domain-Teil, obwohl in der Praxis: serverfault.com/a/721929/167961 Hinweis in den Kommentaren, es kann in diesen Tagen verboten sein
Matthew Lock

@MatthewLock Könnte es eine Intranetadresse sein? Wie bob@companyinternal?
Simone

@ Simone verwendet jemand im wirklichen Leben dieses Schema tatsächlich?
Matthew Lock

4

Die Überprüfung der E-Mail-Adresse ist nicht so einfach, wie es scheint. Es ist theoretisch unmöglich, eine E-Mail-Adresse nur mit einem regulären Ausdruck vollständig zu validieren.

In meinem Blogbeitrag finden Sie eine Diskussion zu diesem Thema und eine F # -Implementierung mit FParsec. [/ shameless_plug]


1
Ich mochte Sie Liste der alternativen Ansätze; sehr interessant.
Luke Quinane

1
Interessanter Artikel. Aber im Ernst, wer schreibt Kommentare und verschachtelte Kommentare in E-Mail-Adressen?
Matthew Lock

3
@matthew Ich weiß nicht, warum die IETF das überhaupt erlaubt hat, aber es ist möglich , also muss eine gründliche Validierung dies berücksichtigen.
Mauricio Scheffer

4

Hier ist meine Antwort: Phils Lösung schlägt für Domänen mit einem Buchstaben wie "jemand@q.com" fehl. Ob Sie es glauben oder nicht, das wird verwendet =) (geht zum Beispiel zu centurylink).

Phils Antwort wird auch nur mit dem PCRE-Standard funktionieren ... also wird C # es nehmen, aber Javascript wird bombardieren. Es ist zu komplex für Javascript. Sie können Phils Lösung also nicht für MVC-Validierungsattribute verwenden.

Hier ist meine Regex. Es funktioniert gut mit MVC-Validierungsattributen.
- Alles vor dem @ wird vereinfacht, so dass zumindest Javascript funktioniert. Ich bin in Ordnung, die Validierung hier zu lockern, solange der Exchange-Server mir keine 5.1.3 gibt. - Alles nach dem @ ist Phils Lösung, die für Domänen mit einem Buchstaben geändert wurde.

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

Für Leute, die vorschlagen, system.net.mail MailMessage () zu verwenden, ist dieses Ding viel zu flexibel. Sicher, C # akzeptiert die E-Mail, aber dann wird der Exchange-Server mit dem Laufzeitfehler 5.1.3 bombardiert, sobald Sie versuchen, die E-Mail zu senden.


das scheint die beste nachdenklichste / vernünftigste / realistischste Antwort zu sein, danke Ralph!
Fattie

Das ist die bisher beste Antwort! Ich kann nicht glauben, dass eine schlechte Lösung, die basket@ballals gültige E-Mail-Adresse akzeptiert wird, die richtige Antwort sowie all diese positiven Stimmen erhalten hat. Danke trotzdem!
Disasterkid

Vielen Dank, dies ist die beste Lösung und sollte als Antwort akzeptiert werden.
Bat_Programmer

3

Wenn Sie wirklich und ich meine wirklich wissen wollen, ob eine E-Mail-Adresse gültig ist ... bitten Sie den Mail-Austauscher, dies zu beweisen, es ist keine Regex erforderlich. Ich kann den Code auf Anfrage bereitstellen.

Die allgemeinen Schritte lauten wie folgt: 1. Hat die E-Mail-Adresse einen Domainnamen-Teil? (Index von @> 0) 2. Fragen Sie mithilfe einer DNS-Abfrage, ob die Domäne über einen Mail-Austauscher verfügt. 3. Öffnen Sie die TCP-Verbindung zum Mail-Austauscher. 4. Öffnen Sie mithilfe des SMTP-Protokolls eine Nachricht an den Server, indem Sie die E-Mail-Adresse als Empfänger verwenden. 5. Analysieren Sie die Antwort des Servers. 6. Beenden Sie die Nachricht, wenn Sie es bis hierher geschafft haben. Alles ist gut.

Dies ist, wie Sie sich vorstellen können, zeitlich sehr teuer und basiert auf SMTP, aber es funktioniert.


Haben Sie Fälschungen, Stubs und / oder Mocks für diese Schnittstellen erstellt?
Markieren Sie A

1
Das wird nicht funktionieren. Das SMTP-Protokoll zur Überprüfung einer E-Mail-Adresse wurde LONG veraltet / nicht verwendet. Es wird als schlechte Praxis angesehen, dies auf Mailservern zu aktivieren, da Spammer diese Funktionalität verwenden.
Chad Grant

Ich werde Ihren Vorschlag auf Punkt 2 halten. Viel zukunftssicherer als nach einem bekannten Domainnamenmuster zu suchen.
Simone

Nitpicking, aber definieren "hat einen Mail-Austauscher" ? Wenn keine MX-Datensätze vorhanden sind, sollte SMTP auf den A / AAAA-Datensatz gemäß RFC2821 / 5321 zurückgreifen. Wenn ein MX-Eintrag vorhanden ist, weist dies möglicherweise immer noch nicht darauf hin, dass ein Mail-Austauscher vorhanden ist (RFC7505). Wirklich, der einzige Weg ist, ihnen eine Mail mit einem Call-to-Action-Link zu senden und darauf zu warten, dass sie antworten ...
jimbobmcgee

2

Im Allgemeinen ist es nicht einfach, einen regulären Ausdruck zum Überprüfen von E-Mail-Adressen zu finden. Zum Zeitpunkt dieses Schreibens muss die Syntax einer E-Mail-Adresse einer relativ hohen Anzahl von Standards entsprechen, und die Implementierung aller Standards in einem regulären Ausdruck ist praktisch nicht durchführbar!

Ich empfehle Ihnen dringend , unser EmailVerify.NET zu testen , eine ausgereifte .NET-Bibliothek, die E-Mail-Adressen nach allen aktuellen IETF-Standards validieren kann (RFC 1123, RFC 2821, RFC 2822, RFC 3696, RFC 4291, RFC 5321 und RFC 5322). , testet die zugehörigen DNS-Einträge, prüft, ob die Zielpostfächer Nachrichten annehmen und sogar feststellen können, ob eine bestimmte Adresse verfügbar ist oder nicht.

Haftungsausschluss: Ich bin der Hauptentwickler für diese Komponente.


Beeindruckend! "Als Nächstes wird versucht, den für die angegebene E-Mail-Adresse verantwortlichen Mail-Austauscher zu kontaktieren, und es wird ein gefälschter SMTP-Dialog mit diesem Server gestartet, der einen echten Mail-Server emuliert. Auf diese Weise wird sichergestellt, dass der Server E-Mails für die Adresse verarbeiten kann. Viele SMTP-Server tatsächlich Geben Sie falsch positive Antworten zurück, um sich vor Spammern zu schützen: Um dieses Problem zu beheben, versucht EmailVerify für .NET schließlich, den Ziel-Mail-Austauscher mehrmals mit verschiedenen fabrizierten Adressen abzufragen. "
Matthew Lock

Danke, @MatthewLock;)
Efran Cobisi

Schön, aber ich sehe nur bezahlte Ausgaben. Pläne für eine Community / OpenSource Edition?
Ohad Schneider

1
@OhadSchneider Ja: Wir bieten eine kostenlose Version unserer E-Mail-Validierungstechnologie über Verifalia an, unseren SaaS- E-Mail-Überprüfungsdienst . Verifalia wird mit kostenlosen Open-Source-SDKs für die wichtigsten Softwareentwicklungsplattformen einschließlich .NET geliefert .
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;
        }

A@b.info kann nicht als gültige E-Mail-Adresse überprüft werden.
Ray Cheng

2

Falls Sie verwenden FluentValidation könnten Sie etwas so einfach wie schreiben:

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

eine kleine Änderung an @Cogwheel Antwort

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

Dies scheint nicht zu helfen ... Console.WriteLine(MailAddress("asdf@asdf.").Address);gibt "asdf @ asdf." Aus, was nicht gültig ist.
Langdon

.net scheint eine eigene Definition von gültig zu haben. verwandte Diskussion
waitforit

2

Hier gibt es viele starke Antworten. Ich empfehle jedoch, einen Schritt zurückzutreten. @Cogwheel beantwortet die Frage https://stackoverflow.com/a/1374644/388267 . In einem Massenvalidierungsszenario kann es jedoch kostspielig sein, wenn viele der zu validierenden E-Mail-Adressen ungültig sind. Ich schlage vor, dass wir ein bisschen Logik anwenden, bevor wir in seinen Try-Catch-Block eintreten. Ich weiß, dass der folgende Code mit RegEx geschrieben werden kann, aber das Verständnis für neue Entwickler kann kostspielig sein. Das ist meine zwei Pence wert:

    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

Die am häufigsten gewählte Antwort von @Cogwheel ist die beste Antwort. Ich habe jedoch versucht, die trim()Zeichenfolgenmethode zu implementieren , damit der gesamte Leerraum des Benutzers vom Anfang bis zum Ende der Zeichenfolge abgeschnitten wird . Überprüfen Sie den Code unten für ein vollständiges Beispiel.

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

Das Risiko besteht darin, dass Sie eine andere E-Mail-Adresse als die Quelle validieren, sodass Sie glauben, Sie könnten E-Mails an die (in diesem Fall) nicht zugeschnittene Version der angegebenen E-Mail-Adresse senden. Ein besserer Ansatz wäre, eine separate Methode zu erstellen SanitizeEmail(string email), bei der das Ergebnis dieser Methode zum Validieren und Senden der E-Mail an verwendet wird.
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

Überprüfen Sie, ob die E-Mail-Zeichenfolge das richtige oder das falsche Format hat 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

/ Verwenden des internen Regex, der beim Erstellen des "neuen EmailAddressAttribute ()" verwendet wird; Komponente in .Net4.5 >>> using System.ComponentModel.DataAnnotations; // So überprüfen Sie eine E-Mail-Adresse ...... Getestet und funktioniert.

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

Sie können auch Folgendes verwenden:

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


es sagt wahr für diese E-Mail: "fulya_42_@hotmail.coö" und es wirft Fehler bei
mandrill

1
Erstens ist die E-Mail gültig für example@example.co oder example@example.com .... Die E-Mail enthält alle gültigen Zeichenfolgen und Kriterien mit Ausnahme des letzten Zeichens "ö", und Sie können einfach eine einfache Bedingung hinzufügen, um dieses Zeichen zu validieren . Zweitens bin ich mir über diesen Mandrill-API-Fehler nicht sicher. Vielleicht möchten Sie Ihre Verwendungsmethode überprüfen, da ich diese Validierung in einer anderen Umgebung / API verwendet habe und sie mir gut getan hat.
Aina Ademola C

1

Ich habe die Antwort von Poyson 1 folgendermaßen zusammengefasst:

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

Der einfache Weg, die E-Mail-ID zu identifizieren, ist gültig oder nicht.

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

Es gibt ein Kulturproblem in Regex in C # und nicht in js. Daher müssen wir Regex im US-Modus für die E-Mail-Prüfung verwenden. Wenn Sie den ECMAScript-Modus nicht verwenden, werden Ihre Sprach-Sonderzeichen in AZ mit Regex angezeigt.

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

Am Ende habe ich diesen regulären Ausdruck verwendet, da er Kommas, Kommentare, Unicode-Zeichen und IP-Domänenadressen (v4) erfolgreich überprüft.

Gültige Adressen sind:

"" @ 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

Eine einfache ohne Regex (die ich wegen ihrer schlechten Lesbarkeit nicht mag):

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

Beispiele:

  • 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

Es soll einfach sein und behandelt daher keine seltenen Fälle wie E-Mails mit Domänen in Klammern, die Leerzeichen enthalten (normalerweise zulässig), E-Mails mit IPv6-Adressen usw.


1

Hier ist eine Antwort auf Ihre Frage, die Sie überprüfen können.

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

Basierend auf der Antwort von @Cogwheel möchte ich eine modifizierte Lösung teilen, die für SSIS und die "Skriptkomponente" funktioniert:

  1. Platzieren Sie die "Skriptkomponente" in Ihrer Datenflussverbindung und öffnen Sie sie.
  2. Setzen Sie im Abschnitt "Eingabespalten" das Feld, das die E-Mail-Adressen enthält, auf "ReadWrite" (im Beispiel "fieldName").
  3. Wechseln Sie zurück zum Abschnitt "Skript" und klicken Sie auf "Skript bearbeiten". Dann müssen Sie warten, nachdem der Code geöffnet wurde.
  4. Platzieren Sie diesen Code in der richtigen Methode:

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

Anschließend können Sie eine bedingte Aufteilung verwenden, um alle ungültigen Datensätze herauszufiltern oder was auch immer Sie tun möchten.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.