提问者:小点点

我的正则表达式匹配得太多了。 我怎么让它停下来? [副本]


我有一个巨大而丑陋的字符串,我试图用正则表达式从它中提取片段。 在本例中,我想抓取“project name”之后的所有内容,直到它说“j0000011:”的部分(11每次都是不同的数字)。

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:\s+(.*)\s+J[0-9]{7}:

问题是,它不会停止,直到它到达最后的j0000020:。

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


共3个答案

匿名用户

.*后面添加“”,使其成为非贪婪的:

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

匿名用户

在这里使用非贪婪的量词可能是最好的解决方案,也因为它比贪婪的替代方案更有效率:贪婪的匹配一般会尽其所能(这里,直到文本的结尾!) 然后一个字符一个字符地追溯以尝试匹配随后出现的部分。

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

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

\s的意思是“除了空白之外的所有内容,这正是您想要的。

匿名用户

嗯,“.*”是一个贪婪的选择器。 您可以通过使用“.*?”使其成为非贪婪的。当使用后一种构造时,regex引擎将在每一步将文本匹配到“。”中,尝试匹配“.*?”后面的任何make。 这意味着,例如,如果“.*?”后面没有任何东西,那么它不匹配任何东西。

这是我用的。 S包含原始字符串。 这段代码是特定于。NET的,但是大多数regex都有类似的内容。

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