如何解析格式为"姓名<电子邮件>"的字符串

5
我有一个方法,可以接收以下任一格式的联系人信息:
1 - "email@domain.com"
2 - "Name " 或者 "Name"(可以存在空格)
如果它是第一种格式,我什么都不做。如果是第二种格式,我需要解析姓名和电子邮件。
我永远不知道我将得到的电子邮件格式是哪种。但是它将是其中之一。
如何实现?
7个回答

15

实际上已经有一个名为MailAddress的.NET类可以为您轻松地完成此操作。
更新:它不仅可以获取显示名称,还可以获取电子邮件地址、用户名和主机。

首先包含using System.Net.Mail,然后您可以使用以下方法获取信息:

MailAddress email = new MailAddress("Johnny <johnny@example.com>");
string displayName = email.DisplayName;
string address = email.Address;
string user = email.User;
string host = email.Host;

这将适用于您所描述的两种情况,即 "Name <email@domain.com>""Name<email@domain.com>" 都可以工作,并为您提供Name。我继续创建了一个测试,可以在此处找到,将为您提供示例输出:

'email@domain.com' =
   DisplayName = ''
   Address = 'email@domain.com'
   User = 'email'
   Host = 'domain.com'
'Name<email@domain.com>' =
   DisplayName = 'Name'
   Address = 'email@domain.com'
   User = 'email'
   Host = 'domain.com'
'Name <email@domain.com>' =
   DisplayName = 'Name'
   Address = 'email@domain.com'
   User = 'email'
   Host = 'domain.com'

很好的发现,但是你可能想在你的演示中使用Address属性来展示它不仅可以提取DisplayName,还可以提取电子邮件。 - Tim Schmelter
@TimSchmelter,谢谢。我继续添加了一些信息来展示更多内容。 - Josh Bowden
是的,你发现得很好。实际上,最后我将其转换为MailAddress,但我不知道MailAddress会自动执行此操作。谢谢。 - Miguel Moura

1

MailAddress 是一个很好的解决方案,但不幸的是 System.Net.Mail 还没有被移植到 .NET Core。

我发现以下正则表达式解决方案对于合理格式的输入有效:

var re = new Regex(@"""?((?<name>.*?)""?\s*<)?(?<email>[^>]*)");
var match = re.match(input);

var name = match.Groups["name"].Value;
var email = match.Groups["email"].Value;

我已经使用以下类型的输入进行了测试:
bob@example.com
<bob@example.com>
Bob Example <bob@example.com>
Bob Example<bob@example.com>
"Bob Example" <bob@example.com>
"Example, Bob J." <bob@example.com>

1

MimeKit 有一个方法 可以实现这个功能:

MailboxAddress addr = MailboxAddress.Parse("Mr. Curious <mrcurious@example.com>"); 

它同样适用于.NET、Mono和.NET Core。


0

有几种方法可以做到这一点,但首先想到的是

String[] parts = someValue.Trim().Split(new char[] {' '},false);

if (parts.Length > 1) then
{
// in format "Name OR Name" or more correctly not in format someone@domain.com
}

我已经纠正了我的代码... 我不能按空格分割,因为在(2)中,联系人和电子邮件之间可能有或没有空格。 - Miguel Moura
你可以在第一个格式中使用空格吗?如果不行,上述内容将确定它是1还是2,这似乎是你所询问的。 - Tony Hopkinson
有空格吗? - Tony Hopkinson
是的,可能会有空格。例如:1- "johnsmith@domain.com"; 2 - "John Smithjohnsmith@domain.com" / "John Smith johnsmith@domain.com" ... 名字和电子邮件之间可能会有一个或多个空格。 - Miguel Moura
这既不是C#也不是VB.NET,无论如何都无法编译。 - Tim Schmelter
那么 / 一些是从哪里来的?现在是 OR 吗?如果您不断更改字符串的特征,我们如何为您提供拆分字符串的代码? - Tony Hopkinson

0

您可以使用正则表达式:

        var str = "Name<email@domain.com>";

        var r = new Regex("(?<name>.*?)<(?<email>.*?)>");

        if(r.IsMatch(str))
        {
            var m = r.Match(str);
            Console.WriteLine(m.Groups["name"].Trim());
            Console.WriteLine(m.Groups["email"]);
        }

在这里我假设您不需要验证电子邮件格式,且名称中没有 < 或 > 字符。


0
你可以设计一个简单的正则表达式(在我看来,这在这种情况下是一个优雅的解决方案),或者使用Split()函数,将'<'作为分隔符,对第一个字符串进行Trim()处理,并从第二个字符串中移除结尾的'>'

是的,我正在尝试使用单个正则表达式(@"<(.*?)>")来完成所有操作,但我似乎缺少了什么... - Miguel Moura

0
你可以使用正则表达式。
^((.*?)\s*?<)(.*?)>?$

如果有的话,名称将在第二个捕获组中,电子邮件将在第三个捕获组中。

例子:

var match = Regex.Match("Name <email@domain.com>", @"^((.*?)\s*?<)(.*?)>?$");
string name = math.Groups[2].Value;
string email = match.Groups[3].Value;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接