#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).*)*