Я думаю, что причина, по которой ваше регулярное выражение не удалит последнюю новую строку, заключается в том, что она является частью конца последней части, которую вы хотите сохранить, поэтому, не сопоставив ее, вы не можете ее удалить.
Поэтому я переписал регулярное выражение, чтобы оно соответствовало строке, которую вы хотите сохранить, а также включило все выше и ниже совпадения, которые не являются другим совпадением.
Ключевое отличие заключается в использовании условного выражения для соответствия только новой строке группы, которую вы хотите сохранить, если за ним следует другое совпадение.
регулярное выражение (разрывы строк для удобства чтения):
((?!(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
Для удобочитаемости я удалил часть логики без захвата и разделителя строк, которая у вас была, если они необходимы, вы можете добавить их обратно.
Логическая разбивка частей:
(?(?=\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*)*
точно такие же и соответствуют всем ненужным вещам, поэтому они удаляются.
09.05.2020