Вы провалить матч с упреждающей выборкой, если 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));
}
}
Спасибо, Wiktor. Я не могу сказать вам, сколько мне задает регулярное выражение головной боли. Я потратил несколько часов на сотню уроков, и я просто не могу обмотать его вокруг. Синтаксис настолько запутанный, что я чувствую, что мне придется использовать его ежедневно в течение нескольких недель, чтобы действительно им стало комфортно, lol! – John
Ну, на самом деле, вы можете сделать все это без регулярного выражения или с более простым '(? S) StartTest. *? EndText' regex, а затем получить только те совпадения, которые не содержат' NoInclude'. Закаленный жадный токен является немного дорогостоящим, хотя механизм .NET regex действительно эффективен. –
Хорошо, я видел, что вы отредактировали это пару раз - мы перешли от простого к чему-то, чего я не понимаю, опять же, lol. Что такое «(?: (?! (?:« Start OR End достаточно просто, но я потерялся оттуда ... Я собирался добавить больше к OP, но, похоже, я не могу. Позвольте мне прочитайте эту ссылку, которую вы указали, посмотрим, смогу ли я где-нибудь с этим справиться. Я действительно волнуюсь в regex ненависти. – John