Требуется регулярное выражение для соответствия нескольким строкам, пока не будет найдено совпадение между общими разделителями

Я пытаюсь написать регулярное выражение, которое вернет несколько строк из файла журнала. Используя пример ниже – я хочу сопоставить всю транзакцию, которая начинается и заканчивается тем же текстом, что и ВСЕ другие транзакции в журнале (начало и конец). Однако между этими строками есть пользовательский идентификатор – в этом случае адрес электронной почты, который будет отличать одну транзакцию от другой.

Start of a transaction. random line 1. random line 2. email1@gmail.com End of a transaction. Start of a transaction. random line 1. random line 2. email1@yahoo.com random line 3. End of a transaction. 

Вот что я начинаю с:

 ^Start(.*?)\n(((.*?)(email1\@gmail\.com)(.*?)|(.*?))\n){1,}End (.*?)\n 

По существу – я хочу сказать: Начните с «Пуск» – и сопоставьте все строки до строки «Конец», но возвращайте только соответствие, если одна из строк содержит определенный адрес электронной почты.

Прямо сейчас – мое регулярное выражение обрабатывает весь файл журнала как одно совпадение, так как предположительно строка 1 содержит «Пуск», а строка X содержит «Конец» и где-то в сотнях строк между ними – их соответствие по электронной почте , Также – приложение Powershell и будет использовать шаблон Select-String, если это имеет значение.

Solutions Collecting From Web of "Требуется регулярное выражение для соответствия нескольким строкам, пока не будет найдено совпадение между общими разделителями"

Используйте отрицательное утверждение lookahead, чтобы убедиться, что ваше регулярное выражение никогда не совпадает с границей «Конец транзакции»:

 preg_match_all( '/^ # Start of line Start\ of\ a\ transaction\. # Match starting tag. (?: # Start capturing group. (?!End\ of\ a\ transaction) # Only match if we\'re not at the end of a tag. . # Match any character )* # any number of times. email1@gmail\.com # Match the required email address (?:(?!End\ of\ a\ transaction).)* # and the rest of the tag. ^ # Then match (at the start of a line) End\ of\ a\ transaction\.\n # the closing tag./smx', $subject, $result, PREG_PATTERN_ORDER); $result = $result[0]; 

Протестируйте его на regex101.com .

Используйте модификатор s для создания . соответствие символов новой строки:

 (?s)Start((?!Start).)*email1\@gmail\.com(.*?)End([^\n]*) 

Примечание : ((?!Start).)* Утверждает отрицательный результат в каждой позиции, в которую мы вошли * модификатором, чтобы гарантировать, что мы находимся в одном блоке за один раз.

Демо-версия