Skip to main content
 首页 » 编程设计

python之正则表达式以在 Python 中以未知的出现顺序捕获不同的元素

2024年12月31日30birdshome

我正在构建一个正则表达式以从 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')