Regex在Python中以未知的出现顺序捕获不同的元素

2024-04-25 06:02:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在构建一个regex来从Python中转发的电子邮件中提取头值。我只对这些邮件头的第一次出现感兴趣,我只想捕捉冒号后面出现的文本部分。你知道吗

From: ...  
Sent: ...   
To: ...   
Subject: ...  

对于上述格式的大多数变体,使用re.search可以很好地使用以下正则表达式:

(?:From\s*:\s*)(.*)(?:\n*)(?:Sent\s*:\s*)(.*)(?:\n*)(?:To\s*:\s*)(.*)(?:\n*)(?:Subject\s*:\s*)

但有时,不同的标题部分的顺序不同,缺少元素,例如:

Sent: ...    
From: ...  
Subject: ... 

我想我可以使用一个积极的前瞻性匹配头格式在任何顺序,但我不能得到这个工作。有人知道如何有效地做到这一点吗?非常感谢您的帮助。你知道吗


Tags: tofrom文本re顺序电子邮件格式邮件
2条回答

一种可能是从不使用任何字符,并使用lookahead在可选组中捕获所需的所有内容:

(?=(?:.*^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')

尝试以下模式:\G(From:|Subject:|Sent:|To:)(.+)\n

它应该只捕获第一个块的要求由\G锚点实现,它确保在上一个块之后满足下一个匹配(Sent/To/From/Subject),所以另一个邮件的头不匹配,因为它将被电子邮件的内容分隔开。你知道吗

Alternation确保它将独立于Sent/To/From/Subject的顺序来匹配报头。你知道吗

Demo

相关问题 更多 >