在JS中从字符串中提取姓名和电子邮件

4

如何从一个字符串中提取姓名和电子邮件地址,其中电子邮件地址由逗号分隔。

下面的正则表达式适用于单个电子邮件地址,但不适用于字符串中的电子邮件地址。

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

请注意名称中的逗号。
johndoe@baidu.com, John <johndoe@google.com>, John D, A <johndoe@bing.com>, "John Doe , Yen" <johndoe@163.com>

输出:

Name: null
Email: johndoe@baidu.com

Name: John
Email: johndoe@google.com

Name: John D, A
Email: johndoe@bing.com

Name: John Doe , Yen
Email: johndoe@163.com

你期望的输出是什么? - hwnd
也试了一下,请看fiddle :) - Jonny 5
2个回答

3

很难确定数据是否会改变或保持不变,但下面是我的尝试:

var re  = /(?:"?([A-Z][^<"]+)"?\s*)?<?([^>\s,]+)/g;

while (m = re.exec(str)) {
  if(m[1]) { m[1] = m[1].trim() }
  console.log("Name: "  + m[1]);
  console.log("Email: " + m[2]);
}

Working Demo


0

这里是一个可能的答案:

(?:^|, *)(?![^",]+")(?:((?=[^"<]+@)|(?![^"<]+@)"?(?<name>[^"<]*)"? *))<?(?<email>[^,>]*)>?

这是使用Ruby正则表达式,并使用前向匹配来确定条目是否有名称。

  1. (?:^|, *): 从字符串的开头开始,或者在一个逗号和若干空格之后开始
  2. (?![^",]+"): 负向先行断言,如果有一些字符然后是",则中止匹配。这样可以防止逗号在字符串内部开始匹配。
  3. (?:((?=[^"<]+@)|(?![^"<]+@)"?(?<name>[^"<]*)"? *)): 匹配名称:

    1. (?=[^"<]+@) 如果在引号或大括号之前出现@,只是一个没有名字的电子邮件地址,所以不进行匹配
    2. (?![^"<]+@)"?(?<name>[^"<]*)"? *: 否则,匹配名称(如果存在开启和关闭引号,则跳过它们)
  4. <?(?<email>[^,>]*)>?: 匹配电子邮件地址。

在rubular上

请注意,在实际工作中,这将是一个可怕的方法。正则表达式几乎是难以理解的,更不用说是脆弱的。它也不完整,例如如果您可以在名称内部转义引号会发生什么?

如果您确实需要它,我会为此编写一个专用解析器。但是,如果您只是想提取一些数据,则正则表达式可能足够好了。


感谢您详细的回答。 - Sijia Din

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