为啥我的正则表达式模式收集的比我预期的要多?

Posted

技术标签:

【中文标题】为啥我的正则表达式模式收集的比我预期的要多?【英文标题】:Why is my regex pattern collecting more than I am expecting?为什么我的正则表达式模式收集的比我预期的要多? 【发布时间】:2021-05-19 15:59:33 【问题描述】:

我正在尝试创建一个正则表达式模式以仅在“发件人”一词之后获取电子邮件地址。

以下是输入示例:

Recip: fhavor@gmail.com
Subject: Report results (Gd)
Headers: Received: from daem.com (unknown [127.1.1.1])
Date: Sat, 13 Feb 2021 13:11:42 +0000 (GMT)
From: Tavon Lo <lt35@gmail.com>
Recip: fhavor2@gmail.com
Subject: Report results (Gd1)
Headers: Received: from daem2.com (unknown [127.1.1.1])
Date: Sat, 14 Feb 2021 13:11:42 +0000 (GMT)
From: Tavon Lo <lt36@gmail.com>
Sender: lt36@gmail.com
Recipient: hi@gmail.com

因此,应该在输出中的唯一电子邮件地址是 lt36@gmail.com

以下是我的正则表达式模式:

(?m)^Sender:([^<>@]+@[^<>]+)

这符合以下内容:

lt36@gmail.com
Recipient: hi@gmail.com

查看正则表达式演示https://regex101.com/r/qRLrAW/1

我只想要 lt36@gmail.com。我是正则表达式模式的新手,所以这可能是一个简单的解决方法,但我被卡住了。关于如何修复正则表达式模式以适应我的目标的任何想法或建议?

【问题讨论】:

使用(?m)^Sender:([^&lt;&gt;@]+@[^&lt;&gt;\n]+) 如果您不需要验证电子邮件是否有效,那么只需捕获Sender: 之后的所有内容,就像(?&lt;=Sender: ).* 一样。只需确保未启用 DOTALL 修饰符。 regex101.com/r/8TLtKt/1 【参考方案1】:

你可以使用

(?m)^Sender:[^\S\r\n]*([^<>@\n\r]+@[^<>\n\r]+)

请参阅regex demo。

详情

(?m)^ - 行首 Sender: - 文字字符串 [^\S\r\n]* - 除 CR 和 LF 之外的零个或多个空格 ([^&lt;&gt;@\n\r]+@[^&lt;&gt;\n\r]+) - 组 1:除&lt;&gt;@、CR 和 LF、@ 之外的一个或多个字符以及除&lt;&gt;@ 之外的一个或多个字符、CR 和 LF。

【讨论】:

您是真正的正则表达式专家。我从你的帖子中学到了很多。感谢您提供有关正则表达式解决方案的详细信息 @JoeFerndz 顺便说一句,您需要获取文本中的第一个匹配项,还是将其与re.findall 一起使用以收集所有匹配项? 这不是我的问题,但我正在查看这个以获取所有项目。所以它用于 re.findall() (看到一行单个结果或一行多个结果的结果会很有趣。我认为对于多个结果,我可以使用 re.findall()。对于单个结果,我打算做[0]) @JoeFerndz 我明白了。好吧,要获得单个匹配项,建议使用re.search。比如m = re.search(pattern, text) 然后if m: print(m.group(1))【参考方案2】:

因为[^&lt;&gt;]+也匹配\n,所以会越过行尾到下一行。

您需要将\n 添加到您的否定字符类中,就像Wiktor Stribiżew 在他的answer 中所做的那样。

【讨论】:

【参考方案3】:

这里的问题是您必须通过将匹配的换行符添加到否定字符类来排除它们。

您还可以将匹配转换为积极的后视:

(?m)(?<=^Sender: )[^<>@\n\r]+@[^<>\r\n]+

Regex demo

如果邮箱地址也不能包含空格,可以用\s代替\r\n

(?m)(?<=^Sender: )[^<>@\s]+@[^<>\s]+

模式匹配:

(?m) 多行的内联修饰符 (?&lt;=^Sender: ) Assert Sender:在字符串开头的左边 [^&lt;&gt;@\s]+@[^&lt;&gt;\s]+ 匹配电子邮件之类的模式,不包括空格和换行符

Regex demo

作为使用PyPi regex module 的示例,您也可以使用\K 来获取匹配项。

【讨论】:

【参考方案4】:

我认为这个表达式对于 where 第一部分将删除 Sender 表达式 where 很有用。和 + 将选择电子邮件区域

(?<=Sender: ).+

【讨论】:

以上是关于为啥我的正则表达式模式收集的比我预期的要多?的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式中的回溯比预期的要快

为啥这个正则表达式模式不能按预期工作?

为啥我的 Service Fabric 参与者使用的磁盘空间比预期的要多?

常春藤下载的罐子比预期的要多

NSM 可变数据。为啥保留计数 1 比我预期的要高?

循环通过 python 正则表达式匹配