13 Stimmen

Beste Methode zum Parsen einer Kette von E-Mail-Adressen

Ich arbeite also mit einigen E-Mail-Kopfdaten, und für die Felder to:, from:, cc: und bcc: können die E-Mail-Adressen auf verschiedene Weise ausgedrückt werden:

First Last <name@domain.com>
Last, First <name@domain.com>
name@domain.com

Und diese Varianten können in ein und derselben Nachricht in beliebiger Reihenfolge in einer durch Komma getrennten Zeichenfolge erscheinen:

First, Last <name@domain.com>, name@domain.com, First Last <name@domain.com>

Ich habe versucht, mit einem Weg zu kommen, um diese Zeichenfolge in separate Vorname, Nachname, E-Mail für jede Person zu analysieren (den Namen weglassen, wenn nur eine E-Mail-Adresse angegeben wird).

Kann mir jemand sagen, wie ich das am besten anstellen soll?

Ich habe versucht, die Kommas zu trennen, was auch funktioniert, außer im zweiten Beispiel, wo der Nachname an erster Stelle steht. Ich nehme an, dass diese Methode funktionieren könnte, wenn ich nach der Aufteilung jedes Element untersuche und prüfe, ob es ein '@' oder '<'/'>' enthält; wenn dies nicht der Fall ist, könnte angenommen werden, dass das nächste Element der Vorname ist. Ist dies ein guter Weg, dies zu tun? Habe ich ein anderes Format übersehen, in dem die Adresse vorliegen könnte?


UPDATE: Vielleicht sollte ich ein wenig zu klären, im Grunde alles, was ich suchen zu tun ist, brechen Sie die Zeichenfolge, die die mehrere Adressen in einzelne Zeichenfolgen, die die Adresse in welchem Format es gesendet wurde. Ich habe meine eigenen Methoden für die Validierung und Extraktion der Informationen aus einer Adresse, es war nur schwierig für mich, herauszufinden, der beste Weg, um jede Adresse zu trennen.

Hier ist die Lösung, die ich mir für dieses Ziel ausgedacht habe:

String str = "Last, First <name@domain.com>, name@domain.com, First Last <name@domain.com>, \"First Last\" <name@domain.com>";

List<string> addresses = new List<string>();
int atIdx = 0;
int commaIdx = 0;
int lastComma = 0;
for (int c = 0; c < str.Length; c++)
{
    if (str[c] == '@')
        atIdx = c;

    if (str[c] == ',')
        commaIdx = c;

    if (commaIdx > atIdx && atIdx > 0)
    {
        string temp = str.Substring(lastComma, commaIdx - lastComma);
        addresses.Add(temp);
        lastComma = commaIdx;
        atIdx = commaIdx;
    }

    if (c == str.Length -1)
    {
        string temp = str.Substring(lastComma, str.Legth - lastComma);
        addresses.Add(temp);
    }
}

if (commaIdx < 2)
{
    // if we get here we can assume either there was no comma, or there was only one comma as part of the last, first combo
    addresses.Add(str);
}

Der obige Code generiert die einzelnen Adressen, die ich im weiteren Verlauf verarbeiten kann.

2voto

Jason Miesionczek Punkte 13968

Hier ist die Lösung, die ich mir für dieses Ziel ausgedacht habe:

String str = "Last, First <name@domain.com>, name@domain.com, First Last <name@domain.com>, \"First Last\" <name@domain.com>";

List<string> addresses = new List<string>();
int atIdx = 0;
int commaIdx = 0;
int lastComma = 0;
for (int c = 0; c < str.Length; c++)
{
if (str[c] == '@')
    atIdx = c;

if (str[c] == ',')
    commaIdx = c;

if (commaIdx > atIdx && atIdx > 0)
{
    string temp = str.Substring(lastComma, commaIdx - lastComma);
    addresses.Add(temp);
    lastComma = commaIdx;
    atIdx = commaIdx;
}

if (c == str.Length -1)
{
    string temp = str.Substring(lastComma, str.Legth - lastComma);
    addresses.Add(temp);
}
}

if (commaIdx < 2)
{
    // if we get here we can assume either there was no comma, or there was only one comma as part of the last, first combo
    addresses.Add(str);
}

2voto

Jakub Míšek Punkte 1019

Die saubere und kurze Lösung ist die Verwendung von MailAddressCollection :

var collection = new MailAddressCollection();
collection.Add(addresses);

Dieser Ansatz analysiert eine Liste von Adressen, die durch einen Doppelpunkt getrennt sind , und validiert sie gemäß RFC. Es wirft FormatException für den Fall, dass die Adressen ungültig sind. Wie in anderen Beiträgen vorgeschlagen, wenn Sie mit ungültigen Adressen umgehen müssen, müssen Sie den Wert selbst vorverarbeiten oder parsen, andernfalls empfehlen, zu verwenden, was .NET ohne Verwendung von Reflexion bietet.

Beispiel:

var collection = new MailAddressCollection();
collection.Add("Joe Doe <doe@example.com>, postmaster@example.com");

foreach (var addr in collection)
{
  // addr.DisplayName, addr.User, addr.Host
}

0voto

Anders Punkte 11538

Sie könnten reguläre Ausdrücke verwenden, um zu versuchen, dies herauszufiltern, versuchen Sie diesen Typ:

^(?<name1>[a-zA-Z0-9]+?),? (?<name2>[a-zA-Z0-9]+?),? (?<address1>[a-zA-Z0-9.-_<>]+?)$

wird übereinstimmen: Last, First test@test.com ; Last, First <test@test.com> ; First last test@test.com ; First Last <test@test.com> . Sie können eine weitere optionale Übereinstimmung in der Regex am Ende hinzufügen, um das letzte Segment von First, Last <name@domain.com>, name@domain.com nach der in spitzen Klammern eingeschlossenen E-Mail-Adresse.

Ich hoffe, das hilft ein wenig!

EDITAR:

und natürlich können Sie jedem der Abschnitte weitere Zeichen hinzufügen, um Zitate usw. für das jeweilige Format zu akzeptieren, in dem der Text gelesen wird. Wie sjbotha erwähnte, könnte dies schwierig sein, da die übermittelte Zeichenfolge nicht unbedingt ein bestimmtes Format hat.

Dieser Link können Sie weitere Informationen zum Abgleich UND zur Überprüfung von E-Mail-Adressen mit regulären Ausdrücken erhalten.

0voto

jle Punkte 9028

So würde ich es machen:

  • Sie können versuchen, die Daten zu standardisieren so weit wie möglich zu vereinheitlichen, d.h. loszuwerden wie z. B. die Symbole < und > und alle Kommas nach dem '.com.' Sie brauchen die Kommas die den Vor- und Nachnamen trennen Namen trennen.
  • Nachdem Sie die zusätzlichen Symbole entfernt haben, setzen Sie jede gruppierte E-Mail Datensatz als Zeichenkette in eine Liste ein. Sie können das .com verwenden, um zu bestimmen, wo die Zeichenkette bei Bedarf aufzuteilen ist.
  • Nachdem Sie die Liste der E-Mail-Adressen in der Liste der Zeichenfolgen haben, können Sie können Sie dann die E-Mail-Adressen weiter aufteilen Adressen weiter aufteilen, indem Sie nur Leerzeichen als die Begrenzung.
  • Der letzte Schritt besteht darin, den Vornamen und den Namen des Nachname, usw. Dies würde geschehen indem die 3 Komponenten überprüft werden auf: ein Komma, was bedeuten würde, dass es sich um der Nachname ist; ein ., das die eigentliche Adresse anzeigt; und was übrig bleibt, ist der Vorname. Wenn kein Komma vorhanden ist, dann ist der Vorname Name der erste, der Nachname der zweite, usw.

    Ich weiß nicht, ob dies die prägnanteste Lösung ist, aber sie würde funktionieren und erfordert keine fortgeschrittenen Programmiertechniken

0voto

Vince Punkte 539

// Basierend auf der Antwort von Michael Perry * // muss first.last@domain.com, first_last@domain.com und verwandte Syntaxen verarbeiten // sucht auch nach Vor- und Nachnamen innerhalb dieser E-Mail-Syntaxen

public class ParsedEmail
{
    private string _first;
    private string _last;
    private string _name;
    private string _domain;

    public ParsedEmail(string first, string last, string name, string domain)
    {
        _name = name;
        _domain = domain;

        // first.last@domain.com, first_last@domain.com etc. syntax
        char[] chars = { '.', '_', '+', '-' };
        var pos = _name.IndexOfAny(chars);

        if (string.IsNullOrWhiteSpace(_first) && string.IsNullOrWhiteSpace(_last) && pos > -1)
        {
            _first = _name.Substring(0, pos);
            _last = _name.Substring(pos+1);
        }
    }

    public string First
    {
        get { return _first; }
    }

    public string Last
    {
        get { return _last; }
    }

    public string Name
    {
        get { return _name; }
    }

    public string Domain
    {
        get { return _domain; }
    }

    public string Email
    {
        get
        {
            return Name + "@" + Domain;
        }
    }

    public override string ToString()
    {
        return Email;
    }

    public static IEnumerable<ParsedEmail> SplitEmailList(string delimList)
    {
        delimList = delimList.Replace("\"", string.Empty);

        Regex re = new Regex(
                    @"((?<last>\w*), (?<first>\w*) <(?<name>[a-zA-Z_0-9\.\+\-]+)@(?<domain>\w*\.\w*)>)|" +
                    @"((?<first>\w*) (?<last>\w*) <(?<name>[a-zA-Z_0-9\.\+\-]+)@(?<domain>\w*\.\w*)>)|" +
                    @"((?<name>[a-zA-Z_0-9\.\+\-]+)@(?<domain>\w*\.\w*))");

        MatchCollection matches = re.Matches(delimList);

        var parsedEmails =
                   (from Match match in matches
                    select new ParsedEmail(
                            match.Groups["first"].Value,
                            match.Groups["last"].Value,
                            match.Groups["name"].Value,
                            match.Groups["domain"].Value)).ToList();

        return parsedEmails;

    }

}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X