在Python中解析以逗号分隔的电子邮件列表,其格式为“Name”<email>

时间:2015-07-23 10:05:12

标签: python regex email

输入(以逗号分隔的列表):

"\"Mr ABC\" <mr@abc.com>, \"Foo, Bar\" <foo@bar.com>, mr@xyz.com"

预期输出(2元组列表):

[("Mr ABC", "mr@abc.com"), ("Foo, Bar", "foo@bar.com"), ("", "mr@xyz.com")]

我实际上可以使用逗号分割,然后使用email.utils.parseaddr(address),直到我意识到名称部分也可以包含逗号,就像上面的“Foo,Bar”一样。

email.utils.getaddresses(fieldvalues)非常接近我的需要,但它接受一个序列,而不是逗号分隔的字符串。

1 个答案:

答案 0 :(得分:3)

您可以使用以下

import re
p = re.compile(r'"([^"]+)"(?:\s+<([^<>]+)>)?')
test_str = '"Mr ABC" <mr@abc.com>, "Foo, Bar" <foo@bar.com>, "mr@xyz.com"'
print(re.findall(p, test_str))

输出:[('Mr ABC', 'mr@abc.com'), ('Foo, Bar', 'foo@bar.com'), ('mr@xyz.com', '')]

请参阅IDEONE demo

正则表达式匹配......

  • " - 双引号
  • ([^"]+) - (第1组)除双引号外的1个或多个字符
  • " - 双引号

然后,使用(?:...)?构造引入了一个可选的非捕获组:(?:\s+<([^<>]+)>)?。它匹配......

  • \s+ - 一个或多个空白字符
  • < - 开放角括号
  • ([^<>]+) - (第2组)开启或关闭尖括号以外的1个或多个字符
  • > - 结束角括号

re.findall函数将所有捕获组都放入元组列表中:

  

如果模式中存在一个或多个组,则返回组列表;如果模式有多个组,这将是一个元组列表。

<强>更新

如果您需要确保电子邮件是元组中的 second 元素,请使用此代码(请参阅demo):

lst = re.findall(p, test_str)
print([(tpl[1], tpl[0]) if not tpl[1] else tpl for tpl in lst])
# => [('Mr ABC', 'mr@abc.com'), ('Foo, Bar', 'foo@bar.com'), ('', 'mr@xyz.com')]