По дате Ноябрь 3rd, 2008

Регулярные выражения в PHP - как найти первое вхождение конца или убираем жадность

Регулярные выражения - сложный на первый взгляд, но удивительно мощный инструмент. Подробное описание синтаксиса регулярных выражений занимает не одну страницу.

Иногда требуется выудить содержимое, заключенное в заранее известные границы. Но как быть, если “последняя” граница не единственная в документе? А при попытке выбрать все совпадения почему-то используется не первое вхождение маски, а последнее. Т.е., при попытке выбрать содержимое всех элементов div1 примерно таким кодом:

preg_match_all ('/<div class="div1">(.*)<\/div>/is', $text,$matches) // где текст содержит следующий код:

<div class=”div1″>
<a href=”href0-1″><img src=”image0-1.jpg”></a>
<a href=”href0-1″><img src=”image0-2.jpg”></a>
<a href=”href0-1″><img src=”image0-3.jpg”></a>
</div>

<div class=”div1″>
<a href=”href1″><img src=”image1.jpg”></a>
</div>
<div class=”div1″>
<a href=”href2″><img src=”image2.jpg”></a>
</div>

Мы получим не три значения, а всего одно, в котором будет всё от первого <div class=”div1″>  до последнего </div> - т. е. практически весь код, кроме самих тегов.

Чтобы получить как задумано массив из трех элементов, достаточно добавить модификатор “нежадности” - Ungreedy:

preg_match_all ('/<div class="div1">(.*)<\/div>/isU‘, $text,$matches)

UPD PHP (в Perl такой функциональности не предусмотрено) Если потребуется внутри такого шаблона задать “жадную” подстроку - добавляем “?” к этой подстроке:
чтобы в примере выудить image0-3.jpg из каждой строки, используем маску /src=”([^”]+?)/is - без символа вопроса будет задействован только первый символ. При добавлении вопроса устанавливается “жадность” - ищем, пока не найдем кавычку. (можно, конечно воспользоваться чем-то вроде /”([^”])”/, но идея - показать “местную” жадность )

Опубликовано Ноябрь 3, 2008 | автор: levik  |  Комментарии (2) »