Regex удалить последнюю новую строку - PullRequest
2 голосов
/ 09 мая 2020

Учитывая следующую строку с разделителями ;


a;; z
toy;d;hh 
toy
;b;;jj
z;
d;23
d;23td
;;io;
b y;b;12
z
a;b;bb;;;34
z

и это регулярное выражение

^(?!(?:(a|d))(?:;|$)).*(\s*\z|$)\R*

, я хочу получить полные строки, у которых 1st. столбец не a или d, и удалите совпадающие строки, чтобы получить это, после замены пустым

a;; z
d;23
d;23td
a;b;bb;;;34

См. демонстрацию

На панели «Замена» есть 5-я пустая строка, которую необходимо удалить.

Я использовал этот \s*\z в прошлом для этой цели. Как здесь реализовано, похоже, что это не работает.

Любая помощь приветствуется

Ответы [ 2 ]

0 голосов
/ 10 мая 2020

Вы можете сопоставить то, что вы хотите удалить, и захватить в группе то, что хотите сохранить.

Чтобы предотвратить удаление последовательностей новой строки между группами захвата, вы можете использовать предложение if (? только для соответствует 0+ последовательностям новой строки Unicode, когда больше нет строки, начинающейся с [ad];

В группе замены используйте 1 $1

^(?:(?![ad];).*\R*)*|^([ad];.*(?:\R[ad];.*)*)(?(?![\s\S]*\R[ad];)\R*)

Пояснение

  • ^ Начало строки
  • (?: Группа без захвата
    • (?![ad];) Если строка не начинается с символа a или d, за которым следует;
    • .*\R* Соответствие всей строке и 0+ раз последовательности символов новой строки Unicode
  • )* Закройте группу и повторите 0+ раз, чтобы соответствовать всем последовательным строкам
  • | Или
  • ^ Начало строки
  • ( Захват группа 1
    • [ad];.* Соответствие a или d с последующим ; и остальная часть строки
    • (?: Группа без захвата
      • \R[ad];.* Соответствует новой строке, a или d, за которыми следует; и остальная часть строки
    • )* Закройте группу и повторите 0+ раз, чтобы сопоставить все последовательные строки
  • ) Закрыть группу 1
  • (? Предложение If, соответствует последовательности новой строки Unicode только в том случае, если шаблон [ad]; больше не встречается
    • (?! Отрицательный просмотр вперед, утверждать, что следующее не является
      • [\s\S]*\R[ad]; Сопоставить шаблон [ad];
    • ) Закрыть просмотр вперед.
    • \R* Если утверждение верно, сопоставить 0+ последовательностей новой строки Unicode
  • ) Закрыть предложение if

    См. демонстрацию Regex

0 голосов
/ 09 мая 2020

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

Итак, я переписал регулярное выражение, чтобы оно соответствовало строке, которую вы хотите сохранить, но также включило все, что выше и ниже совпадения, которое не является другим совпадением.

Ключевое различие заключается в использовании условного , чтобы соответствовать новой строке группы, которую вы хотите сохранить, если за ней следует другое совпадение.

регулярное выражение (разрывы строк для удобочитаемости):

((?!(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*)* точно такие же, и соответствует всего ненужного, чтобы его удалили.

...