我的正则表达式匹配太多。我如何使其停止?

时间:2020-03-05 18:42:02  来源:igfitidea点击:
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  J0000100: Machine name: DEV  J0000100: Project file: E:\mbiek\foo.pf  J0000100: Template file: E:\mbiek\foot.xdt  J0000100: Job name: MBiek  J0000100: Output folder: E:\foo\A0001401  J0000100: Temp folder: E:\foo\Output\A0001401  J0000100: Document 1 - Starting document  J0005000: Document 1 - Text overflowed on page 1 (warning)  J0000101: Document 1 - 1 page(s) composed  J0000102: Document 1 - 1 page(s) rendered at 500 x 647 pixels  J0000100: Document 1 - Completed successfully  J0000020:

我有这个巨大的丑陋字符串,我正尝试使用正则表达式从中提取片段。

在这种情况下,我要抓住"项目名称"之后的所有内容,直到显示" J0000011:"的部分(11每次都将是一个不同的数字)。

这是我一直在玩的正则表达式

Project name:\s+(.*)\s+J[0-9]{7}:

问题在于,它直到击中J0000020才停止。

如何使正则表达式在J [0-9] {7}的首次出现时停止?

解决方案

回答

通过在其后添加"`"使"。*"成为非贪婪:

Project name:\s+(.*?)\s+J[0-9]{7}:

回答

在这里使用非贪婪量词可能是最好的解决方案,也是因为它比贪婪的替代方法更有效:贪婪的匹配通常会尽可能地深入(在这里直到文本的结尾!),然后逐个字符地追溯尝试匹配之后的部分。

但是,请考虑改用否定字符类:

Project name:\s+(\S*)\s+J[0-9]{7}:

\ S表示除空格以外的所有内容,这正是我们想要的。

回答

我还建议我们使用" Expresso"试验正则表达式,它是一个非常好的(免费的)用于正则表达式编辑和测试的实用程序。

它的优点之一是,它的UI公开了许多正则表达式功能,而那些不懂正则表达式的人可能不熟悉,从而使他们很容易学习这些新概念。

例如,当使用UI构建正则表达式并选择" *"时,即使我们不熟悉,也可以选中"越少越好"复选框并查看生成的正则表达式并测试其行为。非贪婪的表情之前。

可在其站点上下载:
http://www.ultrapico.com/Expresso.htm

快递下载:
http://www.ultrapico.com/ExpressoDownload.htm

回答

好吧,"。"是贪婪的选择器。我们可以通过使用"。?"使它变得非贪婪。使用后一种构造时,正则表达式引擎将在每一步将文本匹配到"。"中,以尝试匹配在""之后的任何make。 ?"。这意味着,例如,如果在"。?"之后没有任何内容,则表示没有任何匹配。

这是我用的。 s包含原始字符串。这段代码是.NET特有的,但是大多数正则表达式都具有类似的功能。

string m = Regex.Match(s, @"Project name: (?<name>.*?) J\d+").Groups["name"].Value;