.NET正则表达式否定前瞻 – 我做错了什么?

假设我有:

StartTest NoInclude EndTest StartTest Include EndTest 

我正在使用:

 /StartTest(?!NoInclude)[\s\S]*?EndTest/g 

为什么我要匹配这两个组?

Regexr示例: http ://regexr.com/3db8m

如果在StartTest之后直接出现StartTest ,则使前瞻匹配失败。 你需要一个温和的贪婪令牌 :

 (?s)StartTest(?:(?!(?:Start|End)Test|NoInclude).)*EndTest ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 

请参阅正则表达式演示

正则表达式匹配StartTest ,然后匹配任何非StartTestEndTestNoInclude ,直到EndTest

由于*是贪婪的,它会成为. 尽可能地匹配。 否定前瞻将使其在随后的位置停止匹配以下备选方案:

  • (?:Start|End)TestStartTestEndTest
  • NoInclude – 只是NoInclude

注意 :( (?s)是一个内联修饰符(相当于RegexOptions.Singleline标志),用于修改. 模式中的行为也使它与LF(换行符)匹配。 如果没有此修饰符(或没有RegexOptions.Singleline ),则点匹配除换行符之外的任何字符。

注意2 :如果您在本机代码环境之外测试正则表达式,请确保使用适当的测试程序来表示正则表达式。 regexr.com仅支持JavaScript风格,regex101.com支持JS,PCRE和Python风格,RegexStorm.net / RegexHero.net支持.NET风格。 周围有更多的测试人员,阅读他们支持的内容以及首先不支持的内容。

这是一个C#演示 :

 using System; using System.IO; using System.Text.RegularExpressions; using System.Linq; public class Test { public static void Main() { var input = "StartTest\n NoInclude\nEndTest\n\nStartTest\n Include\nEndTest"; var regex = new Regex(@"(?s)StartTest(?:(?!(?:Start|End)Test|NoInclude).)*EndTest"); var results = regex.Matches(input).Cast() .Select(p => p.Value) .ToList(); Console.WriteLine(string.Join("\n", results)); } }