我正在构建一个正则表达式以从 Python 中的转发电子邮件中提取 header 值。我只对这些标题在电子邮件中的第一次出现感兴趣,我只想捕获出现在冒号之后的文本部分。
From: ...
Sent: ...
To: ...
Subject: ...
对于上述格式的大多数变体,以下正则表达式使用 re.search
可以正常工作:
(?:From\s*:\s*)(.*)(?:\n*)(?:Sent\s*:\s*)(.*)(?:\n*)(?:To\s*:\s*)(.*)(?:\n*)(?:Subject\s*:\s*)
但有时,不同的标题部分顺序不同并且缺少元素,如下所示:
Sent: ...
From: ...
Subject: ...
我想我可以使用正向前瞻来以任何顺序匹配标题格式,但我无法让它工作。有谁知道如何有效地完成这项工作?非常感谢任何帮助。
最佳答案
一种可能性是永远不使用任何字符,并使用前瞻性来捕获可选组中所需的所有内容:
(?=(?:.*^From\s*:\s*)(.*?$)|)(?=(?:.*^Sent\s*:\s*)(.*?$)|)(?=(?:.*^To\s*:\s*)(.*?$)|)(?=(?:.*^Subject\s*:\s*)(.*?$)|)
https://regex101.com/r/pOThDP/2
间隔开,这只是类似模式的 4 次重复,看起来像:
(?=(?:.*^From\s*:\s*)(.*?$)|)
(?=(?:.*^Sent\s*:\s*)(.*?$)|)
(?=(?:.*^To\s*:\s*)(.*?$)|)
(?=(?:.*^Subject\s*:\s*)(.*?$)|)
此外,为了清楚起见,您可能会考虑命名捕获组:
(?=(?:.*^From\s*:\s*)(?P<From>.*?$)|)(?=(?:.*^Sent\s*:\s*)(?P<Sent>.*?$)|)(?=(?:.*^To\s*:\s*)(?P<To>.*?$)|)(?=(?:.*^Subject\s*:\s*)(?P<Subject>.*?$)|)
https://regex101.com/r/pOThDP/3
编辑:python 代码示例:
text = '''To: totext
Sent: sent text
this text has no no "from" label
Subject: subject text'''
pattern = re.compile(r'(?=(?:.*^From\s*:\s*)(.*?$)|)(?=(?:.*^Sent\s*:\s*)(.*?$)|)(?=(?:.*^To\s*:\s*)(.*?$)|)(?=(?:.*^Subject\s*:\s*)(.*?$)|)', flags=re.S | re.M)
match = re.search(pattern, text)
print(match.groups())
输出是:
(None, 'sent text', 'totext', 'subject text')
关于python - 正则表达式以在 Python 中以未知的出现顺序捕获不同的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51818807/