Регулярное выражение php: просмотр назад, просмотр вперед и проблема жадности

Это должно быть просто, но я нуб, и я не могу понять это. Я пытаюсь использовать регулярное выражение для сопоставления текста внутри специальных тегов открытия/закрытия: [p2][/p2]

Итак, в этом тексте:

apple [p2]banana[/p2] grape [p2]lemon[/p2]

он должен соответствовать «банану» и «лимону». Регулярное выражение, которое я разработал до сих пор:

(?<=\[p2\]).+(?=\[\/p2\])

Но это слишком жадно. Оно начинается с "b" в слове "банан" и заканчивается на "n" в слове "лимон", что соответствует банану[/p2] винограду [p2]лимону. Как мне просто сопоставить банан и лимон?


person Jared Henderson    schedule 13.11.2009    source источник
comment
конечно, как только я публикую это, я думаю, что наконец понял это: (?‹=\[p2\]).+?(?=\[\/p2\]) правильно?   -  person Jared Henderson    schedule 14.11.2009


Ответы (2)


Это должно сделать это:

(?<=\[p2\]).+?(?=\[\/p2\])

Я добавил вопросительный знак, чтобы квантификатор не был жадным.

person Franz    schedule 13.11.2009
comment
В качестве альтернативы вы можете указать модификатор U, чтобы указать, что все квантификаторы в шаблоне следует рассматривать как нежадные, например. preg_match('/(?<=\[p2\]).+(?=\[\/p2\])/U', .... Обратите внимание, что символ заглавной U автоматически преобразует знак + в нежадный, а конечный ? (оператор жадности) заставит его демонстрировать поведение, которое вы описываете. Стоит знать. См.: us2.php.net/manual/en/reference. pcre.pattern.modifiers.php - person Dereleased; 14.11.2009
comment
@Dereleased: я не совсем понимаю. В чем именно разница? Однако спасибо за комментарий. - person Franz; 14.11.2009
comment
/U в этом случае является излишним, поскольку имеется только один квантификатор. Но я бы ни в коем случае не использовал /U; это делает ваше регулярное выражение менее переносимым (его поддерживают немногие разновидности регулярных выражений) и менее читаемым. Люди ожидают, что квантификаторы будут жадными, и должны приложить сознательные усилия, чтобы преодолеть это ожидание. Это намного проще сделать, когда вы смотрите на ? рядом с квантификатором. - person Alan Moore; 14.11.2009

Вместо использования модификатора регулярного выражения вы можете использовать стандартный модификатор соответствия в стиле perl и добавить ? после + или *, чтобы указать, что эта конкретная часть не является жадной. Упоминалось выше, но может помочь конкретика.

person kbenson    schedule 13.11.2009