Я думаю, причина того, что ваше регулярное выражение не удаляет последнюю строку новой строки, заключается в том, что это часть конца последней части, которую вы хотите сохранить, поэтому без сопоставления вы не можете ее удалить.
Итак, я переписал регулярное выражение, чтобы оно соответствовало строке, которую вы хотите сохранить, но также включило все, что выше и ниже совпадения, которое не является другим совпадением.
Ключевое различие заключается в использовании условного , чтобы соответствовать новой строке группы, которую вы хотите сохранить, если за ней следует другое совпадение.
регулярное выражение (разрывы строк для удобочитаемости):
((?!(a|d)).*(\s*\z|$)\R*)*
(^(a|d).*(?(?=\R*(.*\s*\R+)*(a|b))\R))
((?!(a|d)).*(\s*\z|$)\R*)*
заменить на $4
->
a;; z
d;23
d;23td
a;b;bb;;;34
Для удобочитаемости я удалил некоторые не захватывающие и разделитель строк logi c у вас есть, если они нужны, вы можете добавить их обратно.
Logi c разбивка по частям:
(?(?=\R*(.*\s*\R+)*(a|b))\R)
условно, только соответствует новой строке \R
, если за (?)
следует (?=)
любые несоответствующие строки (.*\s*\R+)*
, которые заканчиваются новой строкой, за которой следует (a|b)
.
Средняя часть (^(a|d).*(?(?=\R*(.*\s*\R+)*(a|b))\R))
, содержащая это становится замещающей группой $4
. Таким образом, он соответствует строкам, начинающимся с (a|d)
, и все совпадения, кроме последнего, также соответствуют новой строке в конце своей строки.
Начало и конец регулярного выражения ((?!(a|d)).*(\s*\z|$)\R*)*
точно такие же, и соответствует всего ненужного, чтобы его удалили.