Регулярное выражение в php поиск всех совпадений в строке
У меня есть строка, это всегда строка с тегами proxy, core, error, get, но всегда имеющая разный порядок написания тегов. После тега всегда идет двоеточие, затем комментарий тега, все выглядит примерно так:
Core:init Proxy: Attemps is ended. Error: Proxy connect timeout Error: core unknown Core:error parse line
С помощью регулярного выражения я пытаюсь поймать все совпадения, они должны выглядеть так:
Core:init
Proxy: Attemps is ended.
Error: Proxy connect timeout
Error:core unknown
Core:error parse line
...
Используя следующую регулярное выражение (?>(?:core|proxy|error|get)\:(.+?)(?=(core|proxy|error|get)\:)) я получаю почти правильный результат, а точнее все совпадения без последнего вхождения. Я перепробовал массу вариантов написания регулярок и все они работают не правильно. Как мне заставить регулярное выражение ловить все совпадения в строке?
Пример: https://regex101.com/r/V97LNk/1
Еще варианты которые я пробовал: https://regex101.com/r/WzZ9A3/1 и https://regex101.com/r/xCJHOF/1
Так же я играл с PREG_SET_ORDER и PREG_PATTERN_ORDER в функции preg_match_all однако это не дало значимых изменений.
Ответы (1 шт):
Во-первых, уберите всё лишнее: атомарная группировка и экранирование перед двоеточиями не нужны.
Во-вторых, основная проблема — отсутствие альтернативы с концом строки: блок предварительного просмотра вперёд (?=(core|proxy|error|get):) требует наличия core, proxy, error или get, за которыми следует символ :, но если там конец строки, совпадения не будет.
Конец строки можно найти с помощью $ или \z (после этого не может быть ничего, даже символа LF в самом конце строки).
Используйте один из двух шаблонов:
(?:core|proxy|error|get):(.+?)(?=(core|proxy|error|get):|$)
(?:core|proxy|error|get):(.+?)(?=(core|proxy|error|get):|\z)
Возможно, вам больше подойдёт
(core|proxy|error|get):\s*\K.+?(?=\s*(?1):|\z)
Подробности
(core|proxy|error|get)- Захватывающая подмаска №1: одно из указанных слов:- двоеточие\s*- ноль и более пробельных символов\K- оператор, очищающий буфер текущего совпадения (весь текст, найденный до сих пор, удаляется из этого буфера).+?- один и более символов, отличных от перевода строки, как можно меньше(?=\s*(?1):|\z)- блок предварительного просмотра вперёд, который требует наличия ноля и более пробельных символов (\s*), последовательности шаблонов, заданных в подмаске №1 ((?1)), а затем:, или|конец строки\z(можно использовать$тоже).