Удаление из строки HTML тегов в PHP. Очистка текста от лишних html-тегов — Парсинг от А до Я Php удаление html тегов

Задача удалять все или только определенные html-теги из строки часто возникает там, где необходимо предоставить возможность любому посетителю страницы, добавлять новую информацию. Самым обычным примером может быть гостевая книга или система комментариев на сайте. Добавляемый таким образом текст может содержать множество различных тегов, добавленных случайно при копировании текста или намеренно, чтобы внести сообщение как-то "очень оригинально". Стоит отметить так же и злонамеренные попытки внести на сайт вредоносный код в тегах script или попытку испортить верстку страницы лишними тегами.

В любом из перечисленных случаев, возникает необходимость перед записью новой информации, очищать ее от лишних html-тегов.

Полная очистка текста от html-тегов

Часто для таких задач используются регулярные выражения, однако в этой статье рассмотрим самый простой метод – удаление тегов с помощью php-функции strip_tags. Эта функция просто удаляет теги из указанной в параметре строки.

$str_in = "

Мой текст с различными тегами.

" ;
$str_out = strip_tags($str_in);
echo $str_out;

В результате такой обработки в переменной $str_out получим строку без тегов:

Мой текст с различными тегами.

* Стоит обратить внимание, что функция strip_tags убирает только сами теги, оставляя их содержимое между открывающим и закрывающим тегом.

Удаление отдельных html-тегов из текста

Иногда нужно убрать только определенные теги из строки. Здесь мы так же воспользуемся функцией strip_tags, но в этот раз вторым (необязательным) параметром укажем теги, которые нужно сохранить.

Например, при обработке строки, нужно оставить только ссылки:

$str_in = "

Мой текст с различными тегами.

" ;
$str_out = strip_tags($str_in, "" );
echo $str_out;

В результате такой обработки в переменной $str_out получим:

Мой текст с различными тегами.

Таким образом, можно указать все теги, которые допустимы в строке, тогда как все остальные будут удалены.


В данной статье рассмотрен самый простой способ очистки строки от тегов. Рассматривая другие варианты, я буду расширять эту статью. Буду рад, если Вы предложите свои варианты решения этой задачи в комментариях или по электронной почте.

С задачей очистки html от лишних тегов сталкиваются абсолютно все.

Первое, что приходит на ум, это использовать php-функцию strip_tags():
string strip_tags (string str [, string allowable_tags])

Функция возвращает строку, очищенную от тегов. В качестве аргумента allowable_tags передаются теги, которые не надо удалять . Функция работает, но, мягко говоря, неидеально. По ходу, там нет проверки на валидность кода, что может повлечь за собой удаление текста, не входящего в тэги.
Инициативные разработчики сложа руки не сидели — в сети можно найти доработанные функции. Хорошим примером является strip_tags_smart .

Применять или не применять готовые решения — личный выбор программиста. Так сложилось, что мне чаще всего не требуется "универсального" обработчика и бывает удобнее почистить код регулярками.

От чего зависит выбор того или иного способа обработки?

1. От исходного материала и сложности его анализа.
Если вам нужно обрабатывать достаточно простые htmp-тексты, без какой-либо навороченной верстки, ясные, как день:), то можно использовать стандартные функции.
Если в текстах есть определенные особенности, которые надо учесть, то тут-то и пишутся специальные обработчики. В одних может использоваться просто str_replace . Например:

$s = array("’" => "’", // Right-apostrophe (eg in I"m)
"“" => "“", // Opening speech mark
"–" => "—", // Long dash
"â€" => "”", // Closing speech mark
"Ã " => "é", // e acute accent
chr(226) . chr(128) . chr(153) => "’", // Right-apostrophe again
chr(226) . chr(128) . chr(147) => "—", // Long dash again
chr(226) . chr(128) . chr(156) => "“", // Opening speech mark
chr(226) . chr(128) . chr(148) => "—", // M dash again
chr(226) . chr(128) => "”", // Right speech mark
chr(195) . chr(169) => "é", // e acute again
);

foreach ($s as $needle => $replace)
{
$htmlText = str_replace($needle, $replace, $htmlText);
}

Другие могут быть основаны на регулярных выражениях . Как пример:

Function getTextFromHTML($htmlText)
{
$search = array (""]*?>.*?"si", // Remove javaScript
""]*?>.*?"si", // Remove styles
""]*?>.*?"si", // Remove xml tags
"""si", // Remove HTML-tags
""([\r\n])[\s] "", // Remove spaces
""&(quot|#34);"i", // Replace HTML special chars
""&(amp|#38);"i",
""&(lt|#60);"i",
""&(gt|#62);"i",
""&(nbsp|#160);"i",
""&(iexcl|#161);"i",
""&(cent|#162);"i",
""&(pound|#163);"i",
""&(copy|#169);"i",
""(\d);"e"); // write as php

$replace = array ("",
"",
"",
"",
"\\1",
"\"",
"&",
"",
" ",
chr(161),
chr(162),
chr(163),
chr(169),
"chr(\\1)");

Return preg_replace($search, $replace, $htmlText);
}
(В такие минуты как никогда радует возможность preg_replace работать с массивами в качестве параметров). Массив вы при необходимости дополняете своими регулярками. Помочь в их составлении вам может, например, этот конструктор регулярных выражений . Начинающим разработчикам может быть полезной статья "All about HTML tags. 9 Regular Expressions to strip HTML tags" . Посмотрите там примеры, проанализируйте логику.

2. От объемов.
Объемы напрямую связаны со сложностью анализа (из предыдущего пункта). Большое количество текстов увеличивает вероятность, что, пытаясь предусмотреть и почистить все регулярками, вы можете что-нибудь да упустить. В этом случае подойдет метод "многоступенчатой" очистки. То есть очистить сначала, допустим, функцией strip_tags_smart (исходники на всякий случай не удаляем). Потом выборочно просматриваем некоторое количество текстов на выявление "аномалий". Ну и "зачищаем" аномалии регулярками.

3. От того, что надо получить в результате.
Алгоритм обработки может быть упрощен разными способами в зависимости от ситуации. Случай, описанный мной в одной из предыдущих статей , хорошо это демонстрирует. Напомню, текст там находился в div-е, в котором кроме него был еще div с "хлебными крошками", реклама адсенс, список похожих статей. При анализе выборки статей обнаружилось, что статьи не содержат рисунков и просто разбиты на абзацы с помощью . Чтобы не чистить "главный" див от посторонних вещей, можно найти все абзацы (с Simple HTML DOM Parser это очень просто) и соединить их содержимое. Так что прежде чем составлять регулярки для чистки, посмотрите, нельзя ли обойтись малой кровью.

Вообще, между сторонниками парсинга html-кода, основанного чисто на регулярных выражениях, и парсинга, в основе которого лежит анализ DOM-структуры документа, в сети разгораются настоящие холивары. Вот, например, на оверфлоу. Невинный с первого взгляда

У Вас в браузере заблокирован JavaScript. Разрешите JavaScript для работы сайта!

strip_tags

(PHP 3 >= 3.0.8, PHP 4, PHP 5)

strip_tags - Удаляет HTML и PHP тэги из строки Описание string strip_tags (string str [, string allowable_tags])

Эта функция возвращает строку str, из которой удалены HTML и PHP тэги. Для удаления тэгов используется автомат, аналогичный примененному в функции fgetss() .

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

Замечание: Аргумент allowable_tags был добавлен в PHP 3.0.13 и PHP 4.0b3. С версии PHP 4.3.0 удаляются также HTML комментарии.

Внимание

Так как strip_tags() не проверяет корректность HTML кода, незавершенные тэги могу привести к удалению текста, не входящего в тэги.

Пример 1. Пример использования strip_tags() $text = "

Параграф.

Еще немного текста"; echo strip_tags($text); echo "\n\n-------\n"; // не удалять

Echo strip_tags($text, "

"); // Разрешаем ,, echo strip_tags($text, "");

Этот пример выведет:

Параграф. Еще немного текста -------

Параграф.

Еще немного текста

Внимание

Эта функция не изменяет атрибуты тэгов, указанных в аргументе allowable_tags, включая style и onmouseover.

С версии PHP 5.0.0 strip_tags() безопасна для обработки данных в двоичной форме.

У данной функции есть существенный недостаток - это склейка слов при удалении тегов. Кроме этого функция имеет уязвимости. Альтернативная функция аналог strip_tags:

Смотрите также описание функции