С помощью PHP я пытаюсь получить свое регулярное выражение для соответствия приведенным ниже ссылкам шаблонов. Проблема в том, что он также захватывает </ul>
из первого блока текста. Когда я удаляю флаг /s
, он получает только вторую ссылку. Что я делаю неправильно?
/{{\%USERS}}(.*)?{{\%\/USERS}}/s
Вот моя строка.
<ul class="users"> {{%USERS}} <li>{%}</li> {{%/USERS}} </ul> {{%USERS}} hello?!{{%/USERS}}
Почему мое выражение слишком много ловит или слишком мало?
Почему мое выражение слишком много ловит или слишком мало?
Его ловить слишком много, потому что кванторы являются жадными по умолчанию (см. Li-aung Yip answer +1 для этого)
Если вы удаляете модификатор s
он соответствует только второму вхождению, потому что этот модификатор делает .
также соответствуют символам новой строки, поэтому без него невозможно совместить первую часть, потому что между ними есть новые строки.
См. Не жадный ответ
{{\%USERS}}(.*?){{\%\/USERS}}
здесь, в Regexr , хорошее место для проверки регулярных выражений.
Btw. Я удалил ?
после группы захвата, ее не нужно, так как *
соответствует также пустой строке, поэтому нет необходимости делать ее дополнительно необязательной.
Вероятно, вам нужно использовать неживые кванторы.
*
и +
являются «жадными». Они будут соответствовать как можно большему количеству символов.
*?
и +?
являются «неживыми». Они будут соответствовать только нескольким символам, необходимым для перехода к следующей части регулярного выражения.
Итак, в следующей тестовой строке:
<alpha><bravo>
<.+>
будет захватывать <alpha><bravo>
(потому что .
matches ><
также!). <.+?>
будет захватывать <alpha>
. Вот ваше регулярное выражение:
/{{%USERS}}([^{]+({%[^{]+)?){{%/USERS}}/g