使用正则表达式提取电子邮件和姓名

14

从类似这样的字符串中提取名称和电子邮件的正则表达式是什么?

johndoe@example.com
John <johndoe@example.com>
John Doe <johndoe@example.com>
"John Doe" <johndoe@example.com>
可以假设电子邮件地址是有效的。姓名将由电子邮件地址通过单个空格分隔,并且可能会用引号括起来。
预期结果为:
johndoe@example.com
Name: nil
Email: johndoe@example.com

John <johndoe@example.com>
Name: John
Email: johndoe@example.com

John Doe <johndoe@example.com>
Name: John Doe
Email: johndoe@example.com

"John Doe" <johndoe@example.com>
Name: John Doe
Email: johndoe@example.com

这是我目前为止的进展:

(("?(.*)"?)\s)?(<?(.*@.*)>?)

(可以在此处进行测试:http://regexr.com/?337i5


你有哪些有效电子邮件的可能性?请注意,用于验证所有电子邮件的正则表达式可能非常广泛。您需要澄清哪些电子邮件是正确的。 - Rohit Jain
我不需要验证电子邮件。 - hpique
你真的想要找一个能够解析电子邮件的库,无论你使用的是哪种编程语言。虽然正则表达式可以用来解析电子邮件中的每个可能值,但这样做非常繁琐。 - fge
@fge 我不知道这里为什么需要。我可以假设电子邮件是有效的,并且它要么是独立的,要么在<>之间。 - hpique
1
@hpique,正则表达式并不是语言无关的。 - Martin Ender
显示剩余4条评论
6个回答

23

以下正则表达式看起来对所有输入都有效,并且仅使用了两个捕获组:

以下正则表达式似乎适用于所有输入,并且只使用了两个捕获组:

(?:"?([^"]*)"?\s)?(?:<?(.+@[^>]+)>?)

http://regex101.com/r/dR8hL3

感谢@RohitJain和@burning_LEGION介绍了非捕获组和字符排除的想法。


存在一个不必要的非捕获组。仅使用 (?:"?([^"]*)"?\s)?<?(.+@[^>]+)>? 可以得到相同的结果。 - undefined

1
(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))

https://regex101.com/r/pVV5TI/1


1
请使用此正则表达式:"?([^"]*)"?\s*([^\s]+@.+)

第 1 组包含名称

第 2 组包含电子邮件


0
你可以尝试这个(和你的代码相同但改进了),但是在匹配后需要检查返回的组,因为电子邮件可能会在第2组或第3组中返回,具体取决于是否提供了名称。
(?:("?(?:.*)"?)\s)?<(.*@.*)>|(.*@.*)

有没有办法将它保留在同一个捕获组中? - hpique
@hpique: 这取决于您使用的编程语言和正则表达式 flavor。如果支持,可以使用 (?|...) 构造来完成,否则可能需要使 <> 可选。如果需要验证,则可以使用条件语句或任何其他巧妙的构造 :-). - Firas Dib

0

这样你就可以获得带或不带名称的内容,同时去除引号。

\"*?(([\p{L}0-9-_ ]+)\"?)*?\b\ *<?([a-z0-9-_\.]+@[a-z0-9-_\.]+\.[a-z]+)>?

0

虽然@hpique有一个不错的答案,但该解决方案仅在正则表达式中分析名称/电子邮件字符串时才有效。当您有一个包含其他项目(比如电子邮件)的较长消息时,它将无法工作。此外,许多其他解决方案在人名包含中间名(例如:James Herbert Bond <jbond@example.com)时也会失败匹配。

这是我编写的更强大的正则表达式解决方案,可以像您想要的那样获取名字、姓氏和电子邮件,即使字符串中有很多其他内容:

/(?:"?)(\b[A-Z][a-z]+\b ?)(\b[A-Z][a-z]+\b ?)*(?:"?) ?<([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)>|([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)/g

在此处查看上述语法:Regexr 上的示例


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