Регулярное выражение для сопоставления многострочных разделов, начиная с идентификатора и заканчивая конечным идентификатором

#java #regex #regex-group

#java #регулярное выражение #регулярное выражение-группа

Вопрос:

Как написать регулярное выражение, которое будет соответствовать всем многострочным разделам (с разным количеством строк), которые начинаются с заданного идентификатора (до получения ключевого слова end of message).

Пример — я хочу извлечь все разделы, начинающиеся с ключевого слова ‘START’, вплоть до ‘END_OF_MSG’ из заданного текстового блока:

 HELLO
START ABC DEF GHI JKL
QWER RANDOM TEXT 213%@#!
UIOP RANDOMZXCVB123456
START ABC DEF GHI JKL
ZZZZZ RANDOMTEXT213%@#!
11111 RANDOMZXCVB123456
$$$ SOMEMORETEXT
START ABC DEF GHI JKL
QWER RANDOMTEXT213%@#!
$$$ RANDOMZXCVB123456
END_OF_MSG
 

Я бы хотел, чтобы регулярное выражение создавало три раздела:

 START ABC DEF GHI JKL
QWER RANDOM TEXT 213%@#!
UIOP RANDOMZXCVB123456
 
 START ABC DEF GHI JKL
ZZZZZ RANDOMTEXT213%@#!
11111 RANDOMZXCVB123456
$$$ SOMEMORETEXT
 
 START ABC DEF GHI JKL
QWER RANDOMTEXT213%@#!
$$$ RANDOMZXCVB123456
 

До сих пор я разработал регулярное выражение, которое, кажется, делает это почти правильно

 (?m)^START(.|n)*?((?=^START)|END_OF_MSG)
 

Проблема в том, что последний раздел также включает идентификатор END_OF_MSG, который я бы хотел пропустить.
Я также думаю, что это регулярное выражение не выглядит как самый оптимальный способ захвата этих разделов. Есть идеи о том, как это улучшить?

Пример доступен здесь: Regex101

Комментарии:

1. Вы должны заменить ((?=^START)|END_OF_MSG) на (?=^(?:START|END_OF_MSG)) . Кроме (.|n)*? того, замените .*? и добавьте (?s) в начале шаблона.

Ответ №1:

Вы можете сопоставить START , за которым следует остальная часть строки, и сопоставить все последующие строки, которые не начинаются с START END_OF_MSG , используя отрицательный прогноз.

 ^STARTb.*(?:R(?!STARTb|END_OF_MSGb).*)*
 

Объяснение

  • ^ Начало строки
  • STARTb.* Сопоставьте НАЧАЛО, границу слова и остальную часть строки
  • (?: Не группа захвата
    • R Сопоставление последовательности перевода строки
    • (?!STARTb|END_OF_MSGb).* Сопоставьте всю строку, если она не начинается ни с одной из альтернатив, используя отрицательный прогноз
  • )* Закройте группу и повторите ее 0 раз, чтобы сопоставить все строки

В Java с удвоенными обратными косыми чертами

 ^START\b.*(?:\R(?!START\b|END_OF_MSG\b).*)*
 

Демонстрация регулярных выражений | Демонстрация Java