【问题标题】:Parse a comma separated list of emails in Python which are of the format "Name" <email>在 Python 中解析逗号分隔的电子邮件列表,其格式为“名称”<email>
【发布时间】:2015-10-13 13:42:47
【问题描述】:

输入(逗号分隔列表):

"\"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) 非常接近我的需要,但它接受一个序列,而不是逗号分隔的字符串。

【问题讨论】:

标签: python regex email


【解决方案1】:

请使用getaddresses

emails = getaddresses('"Mr ABC" <mr@abc.com>, "Foo, Bar" <foo@bar.com>, "mr@xyz.com"')

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

【讨论】:

  • 这很好用,只是你需要将一个列表传递给 getaddresses: emails = getaddresses(["Mr ABC" , "Foo, Bar" , "mr@xyz.com"]) --> [('ABC先生', 'mr@abc.com'), ('Foo, Bar', 'foo@bar.com'), ('', 'mr@xyz.com')]
【解决方案2】:

你可以使用下面的

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+&lt;([^&lt;&gt;]+)&gt;)?。它匹配...

  • \s+ - 1 个或多个空格字符
  • &lt; - 左尖括号
  • ([^&lt;&gt;]+) -(第 2 组)1 个或多个字符,而不是左尖括号或右尖括号
  • &gt; - 右尖括号

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')]

【讨论】:

  • 这是一个很好的解决方案,但后来我忘了提到我们也可以只包含电子邮件部分的电子邮件,例如“mr@xyz.com”。更新了问题。
  • 我已经更新了答案,请看。请注意,即使电子邮件部分不存在,元组仍将被创建,并且电子邮件将被捕获到组 1,因为它们不在 &lt;&gt; 内。
  • 如果你的输出需要[('Mr ABC', 'mr@abc.com'), ('Foo, Bar', 'foo@bar.com'), ('', 'mr@xyz.com')],你可以使用lst = re.findall(p, test_str) // print([(tpl[1], tpl[0]) if not tpl[1] else tpl for tpl in lst])
猜你喜欢
  • 2018-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-12
  • 1970-01-01
  • 1970-01-01
  • 2019-02-28
  • 1970-01-01
相关资源
最近更新 更多