4

MailAddressクラスは、複数の電子メールを含む文字列を解析する方法を提供しません。MailAddressCollectionクラスはそうしますが、CSVのみを受け入れ、引用符内のコンマは許可しません。これらの制限なしにユーザー入力から電​​子メールのコレクションを作成するためのテキストプロセッサを探しています。

プロセッサは、次のいずれかの形式でコンマまたはセミコロンで区切られた値をとる必要があります。

"First Middle Last" <fml@example.com>
First Middle Last <fml@example.com>
fml@example.com
"Last, First" <fml@example.com>
4

4 に答える 4

2

MailAddressCollection.Add()ルーチンは、コンマ区切りのアドレスリストをサポートします。

Dim mc As New Net.Mail.MailAddressCollection()
mc.Add("Bob <bob@bobmail.com>, mary@marymail.com, ""John Doe"" <john.doe@myemail.com>")
For Each m As Net.Mail.MailAddress In mc
    Debug.Print("{0} ({1})", m.DisplayName, m.Address)
Next

出力:

Bob (bob@bobmail.com)
(mary@marymail.com)
John Doe (john.doe@myemail.com)
于 2012-12-13T01:40:43.607 に答える
1

オープンソースライブラリのDotNetOpenMail(旧)には、ほぼすべての有効な形式の電子メールアドレスを解析できるEmailAddressクラスとEmailAddressCollectionがあります。そこから始めることができます。

于 2010-07-05T18:04:34.923 に答える
1

関連する質問をした後、私はより良い方法に気づきました:

/// <summary>
/// Extracts email addresses in the following formats:
/// "Tom W. Smith" &lt;tsmith@contoso.com&gt;
/// "Smith, Tom" &lt;tsmith@contoso.com&gt;
/// Tom W. Smith &lt;tsmith@contoso.com&gt;
/// tsmith@contoso.com
/// Multiple emails can be separated by a comma or semicolon.
/// Watch out for <see cref="FormatException"/>s when enumerating.
/// </summary>
/// <param name="value">Collection of emails in the accepted formats.</param>
/// <returns>
/// A collection of <see cref="System.Net.Mail.MailAddress"/>es.
/// </returns>
/// <exception cref="ArgumentException">Thrown if the value is null, empty, or just whitespace.</exception>
public static IEnumerable<MailAddress> ExtractEmailAddresses(this string value)
{
    if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException("The arg cannot be null, empty, or just whitespace.", "value");

    // Remove commas inside of quotes
    value = value.Replace(';', ',');
    var emails = value.SplitWhilePreservingQuotedValues(',');
    var mailAddresses = emails.Select(email => new MailAddress(email));
    return mailAddresses;
}

/// <summary>
/// Splits the string while preserving quoted values (i.e. instances of the delimiter character inside of quotes will not be split apart).
/// Trims leading and trailing whitespace from the individual string values.
/// Does not include empty values.
/// </summary>
/// <param name="value">The string to be split.</param>
/// <param name="delimiter">The delimiter to use to split the string, e.g. ',' for CSV.</param>
/// <returns>A collection of individual strings parsed from the original value.</returns>
public static IEnumerable<string> SplitWhilePreservingQuotedValues(this string value, char delimiter)
{
    Regex csvPreservingQuotedStrings = new Regex(string.Format("(\"[^\"]*\"|[^{0}])+", delimiter));
    var values =
        csvPreservingQuotedStrings.Matches(value)
        .Cast<Match>()
        .Select(m => m.Value.Trim())
        .Where(v => !string.IsNullOrWhiteSpace(v));
    return values;
}

このメソッドは、次のテストに合格します。

[TestMethod]
public void ExtractEmails_SingleEmail_Matches()
{
    string value = "a@a.a";
    var expected = new List<MailAddress>
        {
            new MailAddress("a@a.a"),
        };

    var actual = value.ExtractEmailAddresses();

    CollectionAssert.AreEqual(expected, actual.ToList());
}

[TestMethod()]
public void ExtractEmails_JustEmailCSV_Matches()
{
    string value = "a@a.a; a@a.a";
    var expected = new List<MailAddress>
        {
            new MailAddress("a@a.a"),
            new MailAddress("a@a.a"),
        };

    var actual = value.ExtractEmailAddresses();

    CollectionAssert.AreEqual(expected, actual.ToList());
}

[TestMethod]
public void ExtractEmails_MultipleWordNameThenEmailSemicolonSV_Matches()
{
    string value = "a a a <a@a.a>; a a a <a@a.a>";
    var expected = new List<MailAddress>
        {
            new MailAddress("a a a <a@a.a>"),
            new MailAddress("a a a <a@a.a>"),
        };

    var actual = value.ExtractEmailAddresses();

    CollectionAssert.AreEqual(expected, actual.ToList());
}

[TestMethod]
public void ExtractEmails_JustEmailsSemicolonSV_Matches()
{
    string value = "a@a.a; a@a.a";
    var expected = new List<MailAddress>
        {
            new MailAddress("a@a.a"),
            new MailAddress("a@a.a"),
        };

    var actual = value.ExtractEmailAddresses();

    CollectionAssert.AreEqual(expected, actual.ToList());
}

[TestMethod]
public void ExtractEmails_NameInQuotesWithCommaThenEmailsCSV_Matches()
{
    string value = "\"a, a\" <a@a.a>; \"a, a\" <a@a.a>";
    var expected = new List<MailAddress>
        {
            new MailAddress("\"a, a\" <a@a.a>"),
            new MailAddress("\"a, a\" <a@a.a>"),
        };

    var actual = value.ExtractEmailAddresses();

    CollectionAssert.AreEqual(expected, actual.ToList());
}

[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void ExtractEmails_EmptyString_Throws()
{
    string value = string.Empty;

    var actual = value.ExtractEmailAddresses();
}

[TestMethod]
[ExpectedException(typeof(FormatException))]
public void ExtractEmails_NonEmailValue_ThrowsOnEnumeration()
{
    string value = "a";

    var actual = value.ExtractEmailAddresses();

    actual.ToList();
}
于 2010-07-06T16:13:20.473 に答える
0

実際、MailAddressCollectionは、引用符で囲まれたコンマを使用しても、コンマで区切られたアドレスをサポートします。私が最近発見した本当の問題は、CSVリストがすでにASCII文字セットにエンコードされている必要があるということです。Unicodeアドレスの場合はQエンコードまたはBエンコード。

基本クラスライブラリには、このエンコーディングを実行する関数はありませんが、SasaでBエンコーディングを提供しています。また、このスレッドの質問に対処する電子メール解析機能を追加しました。

于 2011-09-26T00:54:32.763 に答える