2016-05-01 8 views

ответ

2

Вы провалить матч с упреждающей выборкой, если NoInclude появляется сразу после . Вам нужен tempered greedy token:

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

См regex demo

регулярное выражение соответствия , затем сопоставляет любой текст, который не , EndTest или NoInclude, до EndTest.

Поскольку * жадный, он сделает так, чтобы он мог .. Отрицательное опережение сделает остановки согласования в местах, которые следуют со следующими альтернативами:

  • (?:Start|End)Test - или EndTest
  • NoInclude - просто NoInclude.

Примечание: (?s) это инлайн модификатор (эквивалент RegexOptions.Singleline флага), который изменяет . поведения в шаблоне, что делает его соответствие LF (перевод строки), тоже. Без этого модификатора (или без RegexOptions.Singleline) точка соответствует любому символу, но символу новой строки.

NOTE2: Если вы тестируете регулярное выражение вне среды исходного кода, убедитесь, что вы используете соответствующий тестер для вашего аромата регулярного выражения. regexr.com поддерживает только JavaScript-вкус, regex101.com поддерживает JS, PCRE и Python, а также поддерживает RegexStorm.net/RegexHero.net. Есть еще много тестировщиков, читайте, что они поддерживают, а что не первое.

Вот C# demo:

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<Match>() 
         .Select(p => p.Value) 
         .ToList(); 
     Console.WriteLine(string.Join("\n", results)); 
    } 
} 
+0

Спасибо, Wiktor. Я не могу сказать вам, сколько мне задает регулярное выражение головной боли. Я потратил несколько часов на сотню уроков, и я просто не могу обмотать его вокруг. Синтаксис настолько запутанный, что я чувствую, что мне придется использовать его ежедневно в течение нескольких недель, чтобы действительно им стало комфортно, lol! – John

+0

Ну, на самом деле, вы можете сделать все это без регулярного выражения или с более простым '(? S) StartTest. *? EndText' regex, а затем получить только те совпадения, которые не содержат' NoInclude'. Закаленный жадный токен является немного дорогостоящим, хотя механизм .NET regex действительно эффективен. –

+0

Хорошо, я видел, что вы отредактировали это пару раз - мы перешли от простого к чему-то, чего я не понимаю, опять же, lol. Что такое «(?: (?! (?:« Start OR End достаточно просто, но я потерялся оттуда ... Я собирался добавить больше к OP, но, похоже, я не могу. Позвольте мне прочитайте эту ссылку, которую вы указали, посмотрим, смогу ли я где-нибудь с этим справиться. Я действительно волнуюсь в regex ненависти. – John