正则表达式只在左侧贪婪(.net)

我试图捕获两个字符串之间的匹配。

例如,我正在寻找Q和XYZ之间出现的所有文本,使用“最快”匹配(不继续向外扩展)。 这个字符串:

马戏团问你好Q SOMETEXT XYZ今天是XYZ好的XYZ日

应该返回:

Q SOMETEXT XYZ

但相反,它返回:

问你好Q SOMETEXT XYZ

这是我正在使用的表达式: Q。*?XYZ

它向左走太远了。 当我在星号后使用问号时,它在骑行方面工作正常。 我怎么能在左侧做同样的事情,并在我第一次离开Q后停下来,让它与右侧的工作方式相同? 我已经尝试过来自http://msdn.microsoft.com/en-us/library/az24scfc.aspx的问号和其他符号,但有些东西我只是想不通。

我是一个正则表达式的新手,所以对此有任何帮助将不胜感激!

好吧,非贪婪的匹配正在运行 – 它获得满足正则表达式的最短字符串。 你必须要记住的是, 正则表达式是一个从左到右的过程 。 所以它匹配第一个Q,然后获得最短的字符数,后跟一个XYZ。 如果你不希望它超过任何Q,你必须使用否定的字符类:

Q[^Q]*?XYZ 

[^ Q]匹配任何一个不是Q的字符。请注意,这只适用于单个字符。 如果您的开场分隔符是多个字符,则必须以不同的方式执行。 为什么? 好吧,取分界符’PQR’,字符串是

 foo PQR bar XYZ 

如果您尝试使用之前的正则表达式,但您将字符类扩展为:

 PQR[^PQR]*?XYZ 

然后你会得到的

 'PQR bar XYZ' 

如你所料。 但如果你的字符串是

 foo PQR Party Time! XYZ 

你没有比赛。 这是因为[]描绘了一个“字符类” – 它恰好匹配一个字符。 使用这些类,您只需列出它们即可匹配一系列字符。

 th[ae]n 

将匹配’than’和’then’,但不是’thin’。 在开头放置一个克拉(’^’)否定了类 – 意思是“匹配除了这些字符之外的任何东西” – 所以通过将我们的单字符分隔符转换为[^ PQR],而不是说“不是’PQR’”,你’说“不’P’,’Q’或’R’”。 如果需要,您仍然可以使用此function,但前提是您100%确定分隔符中的字符仅在您的分隔符中。 如果是这种情况,使用贪婪匹配更快,并且只取消分隔符的第一个字符。 正则表达式是:

 PQR[^P]*XYZ 

但是,如果你不能保证,那么匹配:

 PQR(?:.(?!PQR))*?XYZ 

正则表达式不直接支持负字符串匹配(因为当你考虑它时,它是不可能定义的),所以你必须使用负前瞻

 (?!PQR) 

就是这样一个先行者。 这意味着“断言下几个字符不是这个内部正则表达式”,而不匹配任何字符,所以

 .(?!PQR) 

匹配任何未跟随PQR的字符。 将其包裹在一个组中,以便您可以懒惰地重复它,

 (.(?!PQR))*? 

并且你匹配“不包含我的分隔符的字符串”。 我唯一做的就是添加一个?:来使它成为一个非捕获组。

 (?:.(?!PQR))*? 

根据您用来解析正则表达式的语言,它可能会尝试单独传回每个匹配的组(对于查找和替换很有用)。 这使它无法做到这一点。

快乐regexing!

贪婪的概念只适用于右侧。

要使表达式仅与XYZ之前的最后一个Q匹配,请使它们与它们之间的Q不匹配:

 Q[^Q]*?XYZ