代码之家  ›  专栏  ›  技术社区  ›  Pat

将用户输入文本中的(多个)电子邮件提取为MailAddress格式(.NET)

  •  4
  • Pat  · 技术社区  · 15 年前

    这个 MailAddress 类不提供解析包含多个电子邮件的字符串的方法。这个 MailAddressCollection does ,但它只接受CSV和 . 我正在寻找一个文本处理器来创建一个从用户输入没有这些限制的电子邮件集合。

    处理器应采用以下任何格式的逗号或分号分隔值:

    "First Middle Last" <fml@example.com>
    First Middle Last <fml@example.com>
    fml@example.com
    "Last, First" <fml@example.com>
    
    4 回复  |  直到 12 年前
        1
  •  2
  •   Russell Phillips    12 年前

    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)
    
        2
  •  1
  •   edosoft    15 年前

    开源库 DotNetOpenMail EmailAddressCollection . 你可以从那里开始。

        3
  •  1
  •   Community CDub    8 年前

    问了一个问题之后 related question

    /// <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();
    }
    
        4
  •  0
  •   naasking    14 年前

    实际上,MailAddressCollection确实支持逗号分隔的地址,即使引号中有逗号。这个 real problem I recently discovered CSV列表必须已编码到ASCII字符集,即Unicode地址的Q编码或B编码。

    Sasa . 我还添加了一个电子邮件解析函数来解决这个线程中的问题。

    推荐文章