繁体   English   中英

如何将格式化的 email 地址解析为显示名称和 email 地址?

[英]How to parse formatted email address into display name and email address?

给定 email 地址:“Jim”<jim@example.com>

如果我尝试将其传递给 MailAddress,则会出现异常:

指定的字符串不是电子邮件地址所需的格式。

如何将此地址解析为显示名称 (Jim) 和 C# 中的 email 地址 (jim@example.com)?

编辑:我正在寻找 C# 代码来解析它。

EDIT2:我发现 MailAddress 抛出了异常,因为我在 email 地址字符串的开头有一个空格。

如果您想手动解析电子邮件地址,则需要阅读 RFC2822 ( https://tools.ietf.org/html/rfc822.html#section-3.4 )。 3.4 节讨论地址格式。

但是正确解析电子邮件地址并不容易, MailAddress应该能够处理大多数情况。

根据MailAddress的 MSDN 文档:

http://msdn.microsoft.com/en-us/library/591bk9e8.aspx

它应该能够解析带有显示名称的地址。 他们以"Tom Smith <tsmith@contoso.com>"为例。 也许引号是问题? 如果是这样,只需去掉引号并使用 MailAddress 解析其余部分。

string emailAddress = "\"Jim\" <jim@example.com>";

MailAddress address = new MailAddress(emailAddress.Replace("\"", ""));

如果可以避免,手动解析 RFC2822 不值得麻烦。

对我有用:

string s = "\"Jim\" <jim@example.com>";
System.Net.Mail.MailAddress a = new System.Net.Mail.MailAddress(s);
Debug.WriteLine("DisplayName:  " +  a.DisplayName);
Debug.WriteLine("Address:  " + a.Address);

MailAddress 类有一个解析电子邮件地址的私有方法。 不知道它有多好,但我倾向于使用它而不是自己编写。

尝试:

"Jimbo <jim@example.com>"
new MailAddress("jim@example.com", "Jimbo");

解析出你给的字符串:

string input = "\"Jimbo\" jim@example.com";
string[] pieces = input.Split(' ');
MailAddress ma = new MailAddress(pieces[1].Replace("<", string.Empty).Replace(">",string.Empty), pieces[0].Replace("\"", string.Empty));

尝试:“Jim”<jim@example.com> 不确定它是否会起作用,但我通常在电子邮件客户端中看到它。

string inputEmailString = "\"Jimbo\" <jim@example.com>";
string[] strSet =  inputEmailString.Split('\"','<','>');   

MailAddress mAddress = new MailAddress(strSet[0], strSet[2]);

如果您假设 2 之间始终存在空格,则可以使用 String.Split(' ') 将其拆分为空格。 这会给你一个分割部分的数组。

所以可能是这样的:

string str = "\"Jimbo\" jim@example.com"
string[] parts = str.Trim().Replace("\"","").Split(' ')

要检查的一个问题是,如果显示名称中有空格,它会在您的数组中分成 2 个或多个项目,但电子邮件将始终排在最后。

编辑 - 您可能还需要编辑括号,只需添加替换括号即可。

我刚刚写了这个,它从字符串中获取第一个格式正确的电子邮件地址。 这样你就不必假设电子邮件地址在字符串中的位置

有很大的改进空间,但我需要离开工作:)

class Program
{
    static void Main(string[] args)
    {
        string email = "\"Jimbo\" <jim@example.com>";
        Console.WriteLine(parseEmail(email));
    }

    private static string parseEmail(string inputString)
    {
        Regex r = 
            new Regex(@"^((?:(?:(?:[a-zA-Z0-9][\.\-\+_]?)*)[a-zA-Z0-9])+)\@((?:(?:(?:[a-zA-Z0-9][\.\-_]?){0,62})[a-zA-Z0-9])+)\.([a-zA-Z0-9]{2,6})$");

        string[] tokens = inputString.Split(' ');

        foreach (string s in tokens)
        {
            string temp = s;
            temp = temp.TrimStart('<'); temp = temp.TrimEnd('>');

            if (r.Match(temp).Success)
                return temp;
        }

        throw new ArgumentException("Not an e-mail address");
    }
}

它有点“粗糙和准备就绪”,但适用于您给出的示例:

        string emailAddress, displayname;
        string unparsedText = "\"Jimbo\" <jim@example.com>";
        string[] emailParts = unparsedText.Split(new char[] { '<' });

        if (emailParts.Length == 2)
        {
            displayname = emailParts[0].Trim(new char[] { ' ', '\"' });
            emailAddress = emailParts[1].TrimEnd('>');
        }

要处理嵌入的空格,请在括号上拆分,如下所示:

string addrin = "\"Jim Smith\" <jim@example.com>";
char[] bracks = {'<','>'};
string[] pieces = addrin.Split(bracks);
pieces[0] = pieces[0]
  .Substring(0, pieces[0].Length - 1)
  .Replace("\"", string.Empty);
MailAddress ma = new MailAddress(pieces[1], pieces[0]);

所以,这就是我所做的。 它有点快速和肮脏,但似乎有效。

string emailTo = "\"Jim\" <jim@example.com>";
string emailRegex = @"(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|""(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*"")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])";
string emailAddress = Regex.Match(emailTo.ToLower(), emailRegex).Value;
string displayName = null;

try
{
    displayName = emailTo.Substring(0, emailTo.ToLower().IndexOf(emailAddress) - 1);
}
catch 
{
    // No display name 
}

MailAddress addr = new MailAddress(emailAddress, displayName);

评论?

我不使用这种语言编写代码,但我发现您可能需要检查两个问题:

1- 你不知道它被拒绝的确切原因。 直接的可能性是它有一个 example.com 的黑名单。

2-您想要的真正解决方案可能是实现严格的验证器。 Stack Overflow 可能是开发这个的好地方,因为有很多人有实践经验。

这里有一些你需要的东西:

  1. 修剪空白,显然是多余的。
  2. 解析为单独的部分(显示名称、地址左侧、地址右侧)。
  3. 使用特定于数据结构的验证器验证其中的每一个。 例如,右侧需要是有效的 FQDN(如果您使用的是自由邮件系统,则必须是不合格的主机名)。

这是解决此问题的最佳长期方法。

我可以建议我的基于正则表达式的解决方案来解码电子邮件地址字段值(“发件人”、“收件人”)和字段值“主题”

https://www.codeproject.com/Tips/1198601/Parsing-and-Decoding-Values-of-Some-Email-Message

如果您按照建议使用MailKit ,那么您可以使用 MimeKit.MailboxAddress 的方法 Parse 和 TryParse。 这是一个例子。

[Test]
public void Should_Parse_EmailAddress_With_Alias()
{
    //Arrange
    var expectedAlias = "Jim";
    var expectedAddress = "jim@example.com";
    string addressWithAlias = "\"Jim\" <jim@example.com>";

    //Act
    var mailboxAddressWithAlias = MimeKit.MailboxAddress.Parse(addressWithAlias);

    //Assert
    Assert.AreEqual(expectedAddress, mailboxAddressWithAlias.Address);
    Assert.AreEqual(expectedAlias, mailboxAddressWithAlias.Name);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM