Довольно часто бывает необходимо использовать RegExp-ы (система синтаксического разбора текстовых фрагментов по формализованному шаблону) для обработки html-кода страниц сайта.
В данной заметке я приведу наиболее востребованные из них, +краткий справочник метасимволов, +пример.
Наиболее востребованные шаблоны обработки html-кода
Картинки .GIF | /<img[^>]+?gif.*?>/si |
Аттрибут background | /\s+background=[^\s>]*/si |
Аттрибуты элементов HTML | /\s+ATTRIBUTE=[^\s>]*/si |
Комментарии HTML | /<!— .*?—>/si |
Дублирующиеся возвраты каретки | /([\r\n])[\s]+/si |
Неразрывные пространства | /&(nbsp);/si |
Двухдескрипторный тэг HTML, без содержимого | /<TAGNAME.*?>(.*?)<\/TAGNAME.*?>/si |
Двухдескрипторный тэг HTML вместе с содержимым | /<TAGNAME.*?>.*?<\/TAGNAME.*?>/si |
Двухдескрипторный тэг HTML с определенным аттрибутом, без содержимого | /<TAGNAME.*?ATTRIBUTE=["']*VALUE["']*.*?>(.*?)<\/TAGNAME.*?>/si |
Двухдескрипторный тэг HTML с определенным аттрибутом вместе с содержимым | /<TAGNAME.*?ATTRIBUTE=["']*VALUE["']*.*?>.*?<\/TAGNAME.*?>/si |
Закрывающийся тэг HTML | /<\/TAGNAME.*?>/si |
Однодескрипторный или открывающий двухдескрипторный тэг HTML | /<TAGNAME.*?>/si |
Однодескрипторный или открывающий двухдескрипторный тэг HTML с определенным аттрибутом | /<TAGNAME.*?ATTRIBUTE=["']*VALUE["']*.*?>/si |
Ссылки на почтовые адреса без якоря | /<a.*?href=["']*mailto.*?>(.*?)<\/a.*?>/si |
Ссылки на почтовые адреса с якорем | /<a.*?href=["']*mailto.*?>.*?<\/a.*?>/si |
где:
метасимвол . — один любой символ;
квантификаторы:
* — ноль или более;
+ — одно или более;
? — Ноль или одно
[ ] — символьный класс, на данном месте в строке может стоять один из перечисленных символов
( ) — группировка, для определения для определения области действия и приоритета операций
модификаторы:
i — нечувствительность выражения к регистру символов (англ. case insensitivity);
s — режим соответствия точки символам переноса строки и возврата каретки (dot matches all).
Примеры
1. Вырезание модуля в joomla по условию.
1.1. Настройку $is_remove_module вынести в файл настроек модуля params.ini.
1.2. Пусть в переменной $body у нас содержится html-код страницы.
1.3. Тогда код:
if( $is_remove_module) { $body = preg_replace( '|<!--erase-->.*<!--erase-->|ism', '', $body ); // вырезание модуля } |
вырежет модуль заключенный в комментарии .
Примечание: критично тут необходим модификатор «s», необходимый для многострочного поиска. Тестировать регексы онлайн можно на regexpal.com, локально в regexbuddy.
2. Пример с одного хорошего форума:
Как выпарсить полезную инфу (линк, якорь, цену) из кода:
<td class="il_main"><a href="/projects/131516.html" class="item">Модерация ссылок в каталоге.</a><div class="il_item_descr">Контент-менеджмент, Прочее | сегодня в 15:44</div></td> <td class="il_small"><b class="amount_2">до 50 USD</b></td> |
Решение:
$str = '<td class="il_main"><a href="/projects/131516.html" class="item">Модерация ссылок в каталоге.</a><div class="il_item_descr">Контент-менеджмент, Прочее | сегодня в 15:44</div></td> <td class="il_small"><b class="amount_2">до 50 USD</b></td>'; preg_match_all('/href=\"(.+)\" class=\"item\">(.+)<\/a><div class=\"il_item_descr\">.+<\/div><\/td>\s+<td class=\"il_small\"><b class=\"amount_2\">(.+)<\/b><\/td>/siU', $str, $match); print_r($match); |
Функция print_r($match); выведет следующее:
Array ( [0] => Array ( [0] => href="/projects/131516.html" class="item">Модерация ссылок в каталоге. Контент-менеджмент, Прочее | сегодня в 15:44 до 50 USD ) [1] => Array ( [0] => /projects/131516.html ) [2] => Array ( [0] => Модерация ссылок в каталоге. ) [3] => Array ( [0] => до 50 USD ) )
Спасибо, пригодилось!
Пару слов о том, что означает сочетание символов .*? в статье не помешают.
Подробнее про .*? можно прочесть в wiki-статье про regex, раздел «Жадная и ленивая [соответственно не жадная] квантификация», а кратко это поиск любого html-тега, открывающего и закрывающего, любой длины, в том числе и нулевой. За коммент спасибо.