Страницы

Поиск по вопросам

пятница, 10 января 2020 г.

PHP. Регулярное выражение, допускающее отсутствие некоторых частей

#php #регулярные_выражения


Есть текст, типа: "Осталось  10 часов 15 минут 12 секунд". Некоторые компоненты (часы,
минуты, секунды) могут отсутствовать. Нужно выдернуть циферки и соотнести с часами,
минутами, секундами.
Делаю так:

Осталось\s+(?!(\d+)\s+(час).*?)(?!(\d+)\s+(минут).*?)(?!(\d+)\s+(секунд).*?)


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

P.S. Нашел информацию по (?!...). Они, оказывается, используются только для проверки,
но ничего не выводят.

Каким образом можно одновременно проверить наличие фрагментов и выдернуть данные?
    


Ответы

Ответ 1



Нужно использовать комбинацию из проверяемой части и захватывающей части. Примерно вот так: Осталось\s+((?\d+)\s+час(а|ов)?\s*)?((?\d+)\s+минут(а|ы)?\s*)?((?\d+)\s+секунд(а|ы)?)? После обработки в именованных группах будут требуемые значения. Демо тут (спасибо за наводку @stribizhev)

Ответ 2



Мне кажется, Вы путаете необязательные группы с блоками предварительного просмотра (look-ahead). Вместо (?!...) надо использовать (?:...)?, а окончания отлавливать с помощью \p{L}*: Осталось\s+(?:(\d+)\s+час\p{L}*)?(?:\s*(\d+)\s+минут\p{L}*)?(?:\s*(\d+)\s+секунд\p{L}*)? ^^ ^ Код: $re = '/Осталось\s+(?:(\d+)\s+час\p{L}*)?(?:\s*(\d+)\s+минут\p{L}*)?(?:\s*(\d+)\s+секунд\p{L}*)?/u'; См. демо

Комментариев нет:

Отправить комментарий