简体   繁体   English

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

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

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

If I try to pass this to MailAddress I get the exception:如果我尝试将其传递给 MailAddress,则会出现异常:

The specified string is not in the form required for an e-mail address.指定的字符串不是电子邮件地址所需的格式。

How do I parse this address into a display name (Jim) and email address (jim@example.com) in C#?如何将此地址解析为显示名称 (Jim) 和 C# 中的 email 地址 (jim@example.com)?

EDIT: I'm looking for C# code to parse it.编辑:我正在寻找 C# 代码来解析它。

EDIT2: I found that the exception was being thrown by MailAddress because I had a space at the start of the email address string. EDIT2:我发现 MailAddress 抛出了异常,因为我在 email 地址字符串的开头有一个空格。

If you are looking to parse the email address manually, you want to read RFC2822 ( https://tools.ietf.org/html/rfc822.html#section-3.4 ).如果您想手动解析电子邮件地址,则需要阅读 RFC2822 ( https://tools.ietf.org/html/rfc822.html#section-3.4 )。 Section 3.4 talks about the address format. 3.4 节讨论地址格式。

But parsing email addresses correctly is not easy and MailAddress should be able to handle most scenarios.但是正确解析电子邮件地址并不容易, MailAddress应该能够处理大多数情况。

According to the MSDN documentation for MailAddress :根据MailAddress的 MSDN 文档:

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

It should be able to parse an address with a display name.它应该能够解析带有显示名称的地址。 They give "Tom Smith <tsmith@contoso.com>" as an example.他们以"Tom Smith <tsmith@contoso.com>"为例。 Maybe the quotes are the issue?也许引号是问题? If so, just strip the quotes out and use MailAddress to parse the rest.如果是这样,只需去掉引号并使用 MailAddress 解析其余部分。

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

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

Manually parsing RFC2822 isn't worth the trouble if you can avoid it.如果可以避免,手动解析 RFC2822 不值得麻烦。

Works for me:对我有用:

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

The MailAddress class has a private method that parses an email address. MailAddress 类有一个解析电子邮件地址的私有方法。 Don't know how good it is, but I'd tend to use it rather than writing my own.不知道它有多好,但我倾向于使用它而不是自己编写。

尝试:

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

to parse out the string you gave:解析出你给的字符串:

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

if you make the assumption there is always a space between the 2, you could just use String.Split(' ') to split it on the spaces.如果您假设 2 之间始终存在空格,则可以使用 String.Split(' ') 将其拆分为空格。 That would give you an array with the parts split.这会给你一个分割部分的数组。

so maybe like this:所以可能是这样的:

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

An issue with this to check for is that if the display name has a space in it, it will be split into 2 or more items in your array itself, but the email would always be last.要检查的一个问题是,如果显示名称中有空格,它会在您的数组中分成 2 个或多个项目,但电子邮件将始终排在最后。

Edit - you might also need to edit out the brackets, just add replaces with those.编辑 - 您可能还需要编辑括号,只需添加替换括号即可。

I just wrote this up, it grabs the first well formed e-mail address out of a string.我刚刚写了这个,它从字符串中获取第一个格式正确的电子邮件地址。 That way you don't have to assume where the e-mail address is in the string这样你就不必假设电子邮件地址在字符串中的位置

Lots of room for improvement, but I need to leave for work :)有很大的改进空间,但我需要离开工作:)

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

It's a bit "rough and ready" but will work for the example you've given:它有点“粗糙和准备就绪”,但适用于您给出的示例:

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

To handle embedded spaces, split on the brackets, as follows:要处理嵌入的空格,请在括号上拆分,如下所示:

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

So, this is what I have done.所以,这就是我所做的。 It's a little quick and dirty, but seems to work.它有点快速和肮脏,但似乎有效。

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

Comments?评论?

I don't code in this language, but I see two issues you might want to check:我不使用这种语言编写代码,但我发现您可能需要检查两个问题:

1- You don't know exactly why it was rejected. 1- 你不知道它被拒绝的确切原因。 On immediate possibility was that it has a blacklist for example.com.直接的可能性是它有一个 example.com 的黑名单。

2- The real solution you want is to probably implement a strict validator. 2-您想要的真正解决方案可能是实现严格的验证器。 Stack Overflow is probably a good place to develop this, because there are lots of people with practical experience. Stack Overflow 可能是开发这个的好地方,因为有很多人有实践经验。

Here are a couple things you need:这里有一些你需要的东西:

  1. trim whitespace and obviously cruft.修剪空白,显然是多余的。
  2. parse into individual parts (display name, left-hand-side of address, right-hand side of address).解析为单独的部分(显示名称、地址左侧、地址右侧)。
  3. validate each of these with a data structure specific validator.使用特定于数据结构的验证器验证其中的每一个。 For example, the right-hand side needs to be a valid FQDN (or unqualified hostname if you are on a liberal mail system).例如,右侧需要是有效的 FQDN(如果您使用的是自由邮件系统,则必须是不合格的主机名)。

That's the best long-term approach to solving this problem.这是解决此问题的最佳长期方法。

I can suggest my regex-based solution for decoding email address field values ("From", "To") and field value "Subject"我可以建议我的基于正则表达式的解决方案来解码电子邮件地址字段值(“发件人”、“收件人”)和字段值“主题”

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

If you are using MailKit , as recommended , then you can use the methods Parse and TryParse of MimeKit.MailboxAddress.如果您按照建议使用MailKit ,那么您可以使用 MimeKit.MailboxAddress 的方法 Parse 和 TryParse。 Here's an example.这是一个例子。

[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