Шаблон сопоставления HTML-тегов - PullRequest
0 голосов
/ 27 августа 2010

Я новичок в сопоставлении с образцом, наконец, понял это. Я застрял, пытаясь найти подход к следующей проблеме.

Мне нужно вернуть совпадение (с php preg_match), если присутствует какой-либо из числовых HTML-тегов.

<p></p>
<br>
<h1></h1>
<h2></h2>

И не возвращать совпадения в противном случае. Таким образом, все, что не в списке выше, терпит неудачу, например:

<script></script>
<table></table>

ЭСТ

... И в идеале я хочу использовать белый список безопасных тегов, если это возможно.

Кто-нибудь знает шаблон, который я могу использовать / адаптировать?

Ответы [ 3 ]

6 голосов
/ 27 августа 2010

Несмотря на то, что это не обычная ситуация " Я хочу проанализировать HTML с помощью регулярных выражений ", я все же рекомендовал бы использовать анализатор DOM, проходить по каждому элементу и прерывать работу, если его нет в список разрешенных элементов.

См. Например этот вопрос для начала.

Он может стать почти однострочным при использовании расширения парсера DOM, такого как phpQuery , если оно поддерживает селектор :not и несколько имен тегов - я не знаю, никогда не работал с ним сам но это будет легко узнать. Основные примеры здесь .

2 голосов
/ 27 августа 2010

Regex совершенно не подходит для проверки HTML на «безопасные» теги.Мало того, но в HTML нет безопасных тегов.Любому элементу могут быть заданы атрибуты, которые разрешают внедрение скрипта (например, onclick, style -with-IE- expression() ...).Вы должны проверить каждый атрибут, а также каждый элемент.

Когда на карту поставлена ​​ваша безопасность, вам абсолютно необходим настоящий анализатор HTML (затем вы фильтруете элементы / атрибуты и сериализуете результаты).Существует так много способов обойти проверки на основе регулярных выражений, что это даже не смешно.

Вы можете использовать DOMDocument::loadHTML, а затем выполнить DOM-прогулку, или использовать существующую библиотеку, такую ​​как htmlpurifier..

2 голосов
/ 27 августа 2010
preg_match_all('/<([a-z]*)\b[^>]*>(.*?)</\1>/i'$html,$matches);

Разбивка выражения

Первый / является разделителем

< - начало тега, самое первое <

([a-z]*) начинает совпадать с именем тега, поэтому экземпляр ели <<strong> strong

\b[^>]* говорит, что как только вы нашли пробел, продолжайте искать все слова

> говорит, что хочет, чтобы предыдущий раздел продолжал искать, пока не найдет самый первый >

(.*?) говорит: продолжайте искать и СОБИРАЙТЕ (..) строку внутри, но у нас есть ?, а затем прекращайте поиск, когда вы найдете следующий символ после закрывающей скобки.

</\1> говорит, что я хочу сопоставить, но только если значение внутри совпадает с самым первым совпадением, это делается с помощью \1, как в совпадении , the value of this would be what's found with ([az] *) `.

тогда вы можете использовать preg_match_all, чтобы найти все их с содержимым, вывод массива будет что-то вроде

array(
    0 > THE WHOLE TAG
    1 > TAG NAME
    2 > TAG VALUE
)

Надеюсь, это поможет:)

Exmaple

$allowed = array('b','strong','i','pre','code'); WHITELIST, never blacklist
foreach($matchas as $match)
{
    if(!in_array($match[1],$allowed))
    {
        echo sprintf('The tag %s is disallowed!',$match[1]);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...