У меня есть текстовый файл с набором данных, из которого я хочу удалить некоторые записи. Выглядит это так:

  1. = separator =
  2. данные
  3. нежелательное ключевое слово
  4. данные
  5. = separator =
  6. данные
  7. хотелаKeyword
  8. данные
  9. = separator =
  10. данные
  11. нежелательное ключевое слово
  12. данные
  13. = separator =
  14. данные
  15. хотелаKeyword
  16. данные
  17. = separator =

Я могу использовать определенное ключевое слово для идентификации записей, которые мне не нужны (или не нужны). Я хотел использовать RegEx, используя это ключевое слово и строку-разделитель, чтобы удалить все эти выражения. Удаление «нижней» части записи работает нормально, но когда я пытаюсь удалить «верхний» бит, используя это:

= разделитель =. *? нежелательное ключевое слово

Начало совпадения находится на 1-м доступном = разделителе = (строка 5.), а не на последнем (строка 9) перед ключевым словом end (строка 11), что приводит к удалению требуемых записей.

Возможно ли сопоставить только последний экземпляр этой строки (= разделитель = в фиктивных данных), чтобы только строки с 1. по 3. и с 9. по 10., а не с 1. по 3. и с 5. по 11. были бы заменены?

РЕДАКТИРОВАТЬ:

Или я думаю, просто заставить его читать файл в обратном направлении? Notepad ++ отключает эту опцию для RegEx tho, поэтому не уверен, что это возможно.

2
M.Bugajski 11 Окт 2020 в 16:50

2 ответа

Лучший ответ

Если вы хотите удалить строки с 1 по 3 и строки с 9 по 11, вы можете использовать предварительный просмотр, чтобы предотвратить совпадение всех строк, которые либо начинаются с =separator=, либо содержат нежелательное ключевое слово.

^=separator=.*(?:\R(?!(?:=separator=|.*?\bunwantedKeyword\b)).*)*\R.*?\bunwantedKeyword\b.*\R*

Regex demo

enter image description here

2
The fourth bird 11 Окт 2020 в 14:07

Я бы использовал

(?s)=separator=(?:(?!=separator=).)*?unwantedKeyword

См. доказательство.

Объяснение

--------------------------------------------------------------------------------
  (?s)                     set flags for this block (with . matching \n) 
--------------------------------------------------------------------------------
  =separator=              '=separator='
--------------------------------------------------------------------------------
  (?:                      group, but do not capture (0 or more times
                           (matching the least amount possible)):
--------------------------------------------------------------------------------
    (?!                      look ahead to see if there is not:
--------------------------------------------------------------------------------
      =separator=              '=separator='
--------------------------------------------------------------------------------
    )                        end of look-ahead
--------------------------------------------------------------------------------
    .                        any character
--------------------------------------------------------------------------------
  )*?                      end of grouping
--------------------------------------------------------------------------------
  unwantedKeyword          'unwantedKeyword'
2
Ryszard Czech 11 Окт 2020 в 20:25