如何将格式化的电子邮件地址解析为显示名称和电子邮件地址?

时间:2020-03-06 15:01:49  来源:igfitidea点击:

给定电子邮件地址:" Jim" <[email protected]>

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

The specified string is not in the form required for an e-mail address.

如何在C#中将此地址解析为显示名称(Jim)和电子邮件地址([email protected])?

编辑:我正在寻找Ccode来解析它。

EDIT2:我发现异常是由MailAddress引发的,因为我在电子邮件地址字符串的开头有一个空格。

解决方案

尝试:

"Jimbo <[email protected]>"

new MailAddress("[email protected]", "Jimbo");

解析出我们提供的字符串:

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

尝试:" Jim" <[email protected]>
不知道它是否会起作用,但这就是我通常在电子邮件客户端中看到它的方式。

string inputEmailString = "\"Jimbo\" <[email protected]>";
string[] strSet =  inputEmailString.Split('\"','<','>');   

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

如果我们假设2之间始终有一个空格,则可以使用String.Split('')在空格之间进行拆分。这将为我们提供拆分零件的阵列。

所以也许是这样的:

string str = "\"Jimbo\" [email protected]"
string[] parts = str.Trim().Replace("\"","").Split(' ')

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

编辑我们可能还需要编辑括号,只需添加括号即可。

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

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

class Program
{
    static void Main(string[] args)
    {
        string email = "\"Jimbo\" <[email protected]>";
        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\" <[email protected]>";
        string[] emailParts = unparsedText.Split(new char[] { '<' });

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

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

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

根据MSDN文档中的MailAddress:

http://msdn.microsoft.com/zh-CN/library/591bk9e8.aspx

它应该能够解析一个带有显示名称的地址。他们以" Tom Smith <[email protected]>"为例。也许引号是问题?如果是这样,只需删除引号,然后使用MailAddress解析其余部分即可。

string emailAddress = "\"Jim\" <[email protected]>";

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

如果可以避免的话,手动解析RFC2822是不值得的。

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

string addrin = "\"Jim Smith\" <[email protected]>";
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\" <[email protected]>";
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我们想要的真正解决方案可能是实施严格的验证器。堆栈溢出可能是开发此堆栈的好地方,因为有很多有实践经验的人。

这是我们需要做的几件事:

  • 修剪空白,并且很明显。
  • 解析成各个部分(显示名称,地址的左侧,地址的右侧)。
  • 使用特定于数据结构的验证器来验证每一个。例如,右侧需要为有效的FQDN(如果使用的是自由邮件系统,则必须为不合格的主机名)。

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

为我工作:

string s = "\"Jim\" <[email protected]>";
System.Net.Mail.MailAddress a = new System.Net.Mail.MailAddress(s);
Debug.WriteLine("DisplayName:  " +  a.DisplayName);
Debug.WriteLine("Address:  " + a.Address);

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