Регулярное выражение соответствует последнему вхождению строки из нескольких строк - PullRequest
2 голосов
/ 05 марта 2019

Я пытаюсь сопоставить последние вхождения строки из файла журнала.

[03/03/2019 09:16:36] Moving message 123456789 from NEW to PENDING
[03/03/2019 09:16:36] Retrieving file(s) of type DATAWAREHOUSE for 123456
[03/03/2019 09:16:36] collecting warehouse version 7.3.1 files for 123456...
[03/03/2019 09:16:37] Moving message 123456789 from NEW to PENDING
[03/03/2019 09:16:37] Retrieving file(s) of type DATAWAREHOUSE for 123456
[03/03/2019 09:16:37] collecting warehouse version 7.3.1 files for 123456...
[03/03/2019 09:16:38] Moving message 123456789 from NEW to PENDING
[03/03/2019 09:16:39] Retrieving file(s) of type DATAWAREHOUSE for 123456
[03/03/2019 09:16:40] collecting warehouse version 7.3.1 files for 123456...

Выше приведен пример файла журнала, из которого есть три вхождения указанной ниже строки:

Moving message 123456789 from NEW to PENDING

Мне нужно соответствовать последнему вхождению, чтобы получить соответствующую метку времени " [03/03/2019 09:16:38] ".Но когда все это в одной строке с использованием жадного подхода (. *), Все работает нормально.Но когда они присутствуют в нескольких строках, это не работает.Я не пробовал multiline (m), так как не уверен, как его использовать.Может кто-нибудь помочь мне сконструировать запрос регулярного выражения, чтобы получить эту последнюю отметку времени вхождения?Пример: https://regex101.com/r/fnwPsB/1

Ответы [ 2 ]

1 голос
/ 05 марта 2019

Вот решение, которое не зависит от функции PCRE, используя отрицательный прогноз:

(?s)\[(\d{2}\/\d{2}\/\d{4} \d{2}:\d{2}:\d{2})\] Moving message 123456789 from NEW to PENDING(?!.* Moving message 123456789 from NEW to PENDING)

RegEx Demo

Дата-время доступно в 1-й группе захвата.

Здесь (?!.* Moving message 123456789 from NEW to PENDING) - это отрицательный прогноз, который гарантирует, что мы сопоставим самое последнее вхождение данного шаблона.

1 голос
/ 05 марта 2019

Вы можете использовать

(?s:.*\n)?\K\[(\d{2}\/\d{2}\/\d{4} \d{2}:\d{2}:\d{2})\] Moving message 123456789 from NEW to PENDING

См. Демоверсию regex

Детали

  • (?s:.*\n)? - встроенная группа модификаторов, которая соответствует любым 0+ символам, насколько это возможно, вплоть до последнего LF-символа, за которым следует последнее вхождение последующих шаблонов.
  • \K - оператор сброса совпадений удаляет весь найденный текст из буфера памяти совпадений
  • \[(\d{2}\/\d{2}\/\d{4} \d{2}:\d{2}:\d{2})\] Moving message 123456789 from NEW to PENDING - конкретный шаблон линии, который нужно получить с датой и временем, захваченными в группе 1.

В качестве альтернативы используйте

(?s)(\[\d{2}\/\d{2}\/\d{4} \d{2}:\d{2}:\d{2}\] Moving message 123456789 from NEW to PENDING)(?!.*(?1))

См. это демо регулярных выражений .

Детали

  • (?s) - модификатор DOTALL . соответствует любому символу
  • (\[(\d{2}\/\d{2}\/\d{4} \d{2}:\d{2}:\d{2})\] Moving message 123456789 from NEW to PENDING) - необходимый шаблон для сопоставления, записанный в группе 1 и дате и времени в группе 2
  • (?!.*(?1)) - отрицательный прогноз, который не дает совпадения, если существует тот же шаблон, что и в группе 1, после любых 0+ символов справа от текущей позиции.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...