.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
,然后匹配任何非StartTest
, EndTest
或NoInclude
,直到EndTest
。
由于*
是贪婪的,它会成为.
尽可能地匹配。 否定前瞻将使其在随后的位置停止匹配以下备选方案:
-
(?:Start|End)Test
–StartTest
或EndTest
-
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)); } }