Жадная и ленивая квантификация в регулярных выражениях (U в php)

Жадная квантификация - это что-то вроде "установки" (способа реализации) механизма поиска по регулярному выражению , при которой ищется максимально длинная подходящая строка.

А вот при ленивой квантификаци, напротив ищется строка наиболее короткая.

Пример управления жадностью в регулярных выражениях

Рассмотрим пример, где у нас есть html код (фрагмент разметки):

<p><strong> IT FOR FREE </strong> == развитие & взаимодействие. </p>

-- это абзац (ибо окружён тэгом пэ) внутри которого, есть выделенный жирным фрагмент.

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

Рассмотрим варианты решения (тестировать можно например на regex101.com):
Если мы применим регулярное выражение

<.*>

, то кантификатор * который по умолчанию работает как жадный, захватит не тэг, конкретный тэг, а вообещ всю строку -- ведь она тоже окружена угловыми скобками.

Чтобы умерить пыл квантификатора * (звездочка) -- т.е. сделать его ленивым, мы модем сделать следующее:

  • Исключить символы закрывающей скобки -- то есть применить выражение вида:
    <[^>]*>

    -- фактически мы тут явно говорим, что хотим видеть слова окражённые угловыми скобками, но внутри этих скобок, но внутри этих скобок закрывающей скобки не содержащие (что, согласитесь, более точно определяет тэг)

  • Другой путь -- выключить жадность квантификатора *, в PHP это можно сделать тремя способами (первые два через модификатор U -- и однин через знак вопроса):
    1. Установить модификатор выключающий жадность "глобально", для этого модификатор ставится обычным образом:
      /<.*>/U
    2. Или же выключить её перед непосредственно перед фрагментом, к которому применён квантификатор, используя установка внутреених опций и модификатор U:
      <(?U).*>
    3. А можно просто добавить знак вопроса после квантификатора, что сделает его ленивым:
      <.*?>

Модификатор U в PHP

как сказано здесь =
U (PCRE_UNGREEDY) - Этот модификатор инвертирует жадность квантификаторов, таким образом они по умолчанию не жадные. Но становятся жадными, если за ними следует символ '?'. Такая возможность не совместима с Perl. Модификатор U также может использоваться внутри шаблона, при помощи '?U' записи.

vedro-compota's picture

Примечаение: чтобы искать все тэги в строке (на php), на практике в регулярным выражениям выше надо добавлять модификатор g

_____________
матфак вгу и остальная классика =)