Regex Negative Lookbehind 匹配 Lookbehind 文本 .NET

Regex Negative Lookbehind Matches Lookbehind text .NET

假设我有以下字符串:

PB-GD2185-11652-MTCH
GD2185-11652-MTCH
KD-GD2185-11652-MTCH
KD-GD2185-11652

如果字符串中包含 MTCH 且不以 PB 开头,我希望 REGEX.IsMatch 为 return true。

我预计正则表达式如下:

^(?<!PB)\S+(?=MTCH)

但这给了我以下匹配项:

PB-GD2185-11652-
GD2185-11652-
KD-GD2185-11652-

我不明白为什么负向回溯不仅不排除匹配,还包括匹配中的 PB 字符。积极的前瞻工作按预期进行。

编辑 1

让我从一个更简单的例子开始。以下正则表达式匹配我期望的所有字符串:

\S+

以下正则表达式仍然匹配所有字符串,尽管我不希望它匹配:

\S+(?!MTCH)

以下正则表达式匹配前三个字符串中除最后一个 H 字符外的所有字符:

\S+(?<!MTCH)

根据 regex 101 的文档,先行查找模式右侧的文本,后行查找模式左侧的文本,因此在字符串开头进行先行查找与文档。

编辑 2

再举一个例子,下面三个字符串:

grey
greyhound
hound

正则表达式:

 ^(?<!grey)hound 

只匹配最后的猎犬。而正则表达式:

^(?<!grey)\S+ 

三个都匹配。

您需要先看一下:^(?!PB)\S+(?=MTCH)。使用后视意味着 PB 必须出现在第一个字符之前。

问题出在\S+的贪心上。在处理环视和贪婪量词时,您可以轻松匹配比预期更多的字符。解决此问题的一种方法是在具有贪婪量词的组中插入否定环视,以将其排除为匹配项,如以下问题所述:

How to non-greedy multiple lookbehind matches

在这个关于正则表达式贪婪的有用网站上:

http://www.rexegg.com/regex-quantifiers.html

请注意,第二个 link 有一些其他方法来处理各种情况下的贪婪。

针对这种情况的一个好的正则表达式如下:

^(?<!PB)((?!PB)\S+)(MTCH)

在这种情况下,在代码中按逻辑进行操作会更加清晰。所以首先检查字符串是否匹配 MTCH 然后它不匹配 ^PB