我的正则表达式匹配太多。我如何让它停止? [复制]
Posted
技术标签:
【中文标题】我的正则表达式匹配太多。我如何让它停止? [复制]【英文标题】:My regex is matching too much. How do I make it stop? [duplicate] 【发布时间】:2022-01-21 17:43:12 【问题描述】:我有这个又大又丑的字符串:
J0000000: Transaction A0001401 started on 8/22/2008 9:49:29 AM
J0000010: Project name: E:\foo.pf
J0000011: Job name: MBiek Direct Mail Test
J0000020: Document 1 - Completed successfully
我正在尝试使用正则表达式从中提取片段。在这种情况下,我想抓取 Project Name
之后的所有内容,直到它显示 J0000011:
的部分(11 每次都是不同的数字)。
这是我一直在玩的正则表达式:
Project name:\s+(.*)\s+J[0-9]7:
问题是它直到最后碰到 J0000020: 才会停止。
如何使正则表达式在第一次出现 J[0-9]7
时停止?
【问题讨论】:
项目名称:[^\n]*\n(J[0-9]7) 【参考方案1】:通过在 .*
后面添加“?
”使 .*
不贪婪:
Project name:\s+(.*?)\s+J[0-9]7:
【讨论】:
【参考方案2】:在这里使用非贪婪量词可能是最好的解决方案,也因为它比贪婪替代方案更有效:贪婪匹配通常会尽可能远(这里,直到文本结尾!)然后回溯一个接一个的字符来尝试匹配后面的部分。
但是,请考虑改用否定字符类:
Project name:\s+(\S*)\s+J[0-9]7:
\S
表示“除了空格之外的所有内容,这正是您想要的。
【讨论】:
如果可以实现,贪婪的负(或正)字符类通常会比惰性量词表现得更好。懒惰要求引擎逐个字符向前跟踪,检查每次遵循的模式,直到匹配;贪婪的字符类可以盲目地重复所需的字符,这可以快得多。因此,您可能会考虑为否定字符类制定更强有力的案例,因为这是贪婪与懒惰的规范。【参考方案3】:好吧,".*"
是一个贪心选择器。您可以通过使用".*?"
使其不贪婪。当使用后一种构造时,正则表达式引擎将在每一步将文本匹配到"."
中,尝试匹配".*?"
之后的任何内容。这意味着,如果".*?"
之后没有任何内容,则它不会匹配任何内容。
这是我使用的。 s
包含您的原始字符串。此代码是 .NET 特定的,但大多数正则表达式都有类似的内容。
string m = Regex.Match(s, @"Project name: (?<name>.*?) J\d+").Groups["name"].Value;
【讨论】:
【参考方案4】:我还建议您使用“Expresso”来试验正则表达式 - 它是一个用于正则表达式编辑和测试的出色(免费)实用程序。
它的一个优点是它的 UI 公开了许多不熟悉 regex 的人可能不熟悉的 regex 功能,以方便他们学习这些新概念。
例如,当使用 UI 构建正则表达式并选择“*”时,您可以选中“尽可能少”复选框并查看生成的正则表达式,并测试其行为,即使您以前不熟悉非贪婪的表达方式。
可在他们的网站上下载: http://www.ultrapico.com/Expresso.htm
快速下载: http://www.ultrapico.com/ExpressoDownload.htm
【讨论】:
已经有一些很棒的网站了。我宁愿访问书签也不愿在我的计算机上安装其他程序。【参考方案5】:(项目名称:\s+[AZ]:(?:\\w+)+.[a-zA-Z]+\s+J[0-9]7)(?=:)
这对你有用。
添加 (?:\\w+)+.[a-zA-Z]+ 将比 .* 更具限制性
【讨论】:
以上是关于我的正则表达式匹配太多。我如何让它停止? [复制]的主要内容,如果未能解决你的问题,请参考以下文章