匹配意外值的正则表达式模式

时间:2015-06-10 05:49:14

标签: python regex

我正在使用以下python正则表达式代码来分析电子邮件的“收件人”字段中的值:

import re

PATTERN = re.compile(r'''((?:[^(;|,)"']|"[^"]*"|'[^']*')+)''')
list = PATTERN.split(raw)[1::2]

列表应根据","输出每个收件人的姓名和地址。或";"作为分隔符。如果这些值在引号内,则它们将被忽略,这是名称的一部分,通常是:"姓氏,名字"

大多数时候这种方法效果很好,但在下面的例子中我会遇到意想不到的行为:

"Some Name | Company Name" <name@example.com>

在这种情况下,它正在分裂&#34; |&#34;字符。即使我检查正则表达式测试人员网站上的模式,它也会选择整个名称和地址。我做错了什么?

示例输入为:

"Some Name | Company Name" <name1@example.com>, "Some Other Name | Company Name" <name2@example.com>, "Last Name, First Name" <name3@example.com>

2 个答案:

答案 0 :(得分:2)

这不是您问题的直接答案,而是您似乎正在解决的问题,因此可能仍然有用:

要解析电子邮件,我总是大量使用Python的email library

在你的情况下你可以使用这样的东西:

from email.utils import getaddresses
from email import message_from_string

msg = message_from_string(str_with_msg_source)
tos = msg.get_all('to', [])
ccs = msg.get_all('cc', [])
resent_tos = msg.get_all('resent-to', [])
resent_ccs = msg.get_all('resent-cc', [])
all_recipients = getaddresses(tos + ccs + resent_tos + resent_ccs)
for (name, address) in all_recipients:
    # do some postprocessing on name or address if necessary

在我的案例中,这始终可靠地分解邮件标题中的名称和地址。

答案 1 :(得分:1)

您可以使用更简单的正则表达式使用环顾四周来分割文本。

r'(?<=>)\s*,\s*(?=")'

正则表达式解释

  • \s*,\s*匹配,,其中包含零个或多个空格(\s*

  • (?<=>)看看断言。检查,前面是>

  • (?=")向前看断言。检查,后面是"

<强>测试

>>> re.split(r'(?<=>)\s*,\s*(?=")', string)
['"Some Name | Company Name" <name1@example.com>', '"Some Other Name | Company Name" <name2@example.com>', '"Last Name, First Name" <name3@example.com>']

<强>更正

  • 案例1 在上面的示例中,我们使用了单个分隔符,。如果您希望根据多个分隔符进行拆分,则可以使用字符类

    r'(?<=>)\s*[,;]\s*(?=")'
    
    • [,;]字符类,匹配,;
  • 案例2 如评论中所述,如果地址部分缺失,我们需要做的就是将"添加到后面的内容

    示例

    >>> string = '"Some Other Name | Company Name" <name2@example.com>, "Some Name, Nothing", "Last Name, First Name" <name3@example.com>' 
    
    >>> re.split(r'(?<=(?:>|"))\s*[,;]\s*(?=")', string)
    ['"Some Other Name | Company Name" <name2@example.com>', '"Some Name, Nothing"', '"Last Name, First Name" <name3@example.com>']