Компьютерные уроки для начинающих

Компьютерные уроки для начинающих

» » Безбрежный tags php. PHP: как убрать HTML теги из текста? Удаление отдельных html-тегов из текста

Безбрежный tags php. PHP: как убрать HTML теги из текста? Удаление отдельных html-тегов из текста

Проверка и обработка входящих данных является одной из распространённых задач в программировании. Язык PHP обычно используется для веб-приложений, поэтому здесь наиболее актуально удаление HTML тегов из текста, ведь именно они наиболее подверженны сторонним инъекциям. В данной статье я хочу напомнить Вам о старичке stip_tags() и его фишках, а также предложить решения для удаления секционных HTML тегов и ещё парочку полезных бонусов вдогонку.

И так. Основным нашим инструментом для удаления HTML тегов из текста является функция strip_tags (). Мы передаём ей строковое значение, а она удаляет из него HTML и PHP теги, например:

$s = "

Параграф.

Еще текст.";
echo strip_tags($s);

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

Параграф. Еще текст.

Примечательно здесь то, что у функции имеется и второй (не обязательный, но полезный) параметр, значением которого является строка с перечнем разрешенных HTML тегов, например:

$s = "

Параграф.

Еще текст.";
echo strip_tags($s, "

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

Параграф.

Еще текст.

По моему, очень удобно. Тем не менее, это не решает одну важную проблему - удаление секционных HTML тегов , например: script , noscript и style - они наиболее распространённые. Когда мне нужно убрать такие секционные теги, а также варианты начинающиеся с « < » и заканчивающиеся символом « > », я использую следующий PHP код:

$p = array(
""]*?>.*?"si",
""]*?>.*?"si",
""]*?>.*?"si",
"""si",
);
$r = array(" "," "," "," ");
$s = preg_replace($p, $r, $s);

Здесь переменная $p содержит массив регулярных выражений, а $r - массив соответствующей их замены (я использую пробелы) . Осталось лишь провести замену в строке, и мы уберём HTML мусор из текста.

Очевидно, что два выше приведённых решения можно совместить. В начале я использую замену через регулярные выражения, а потом strip_tags() и у меня получается своя функция nohtml() .

Напоследок хочу предложить Вам ещё несколько полезных решений. Так в тексте лучше заменить табуляцию пробелом, результат интерпретации того и другого в браузере идентичны, а хлопот будет меньше, например:

$s = str_replace("\t", " ", $s);

Если Вам не нужны переносы строк, их тоже можно заменить пробелами, например:

$s = str_replace(array("\n", "\r"), " ", $s);

От лишних же пробелов можно избавиться простым регулярным выражением, например:

$s = preg_replace("/\s+/", " ", $s);
$s = trim($s); // будет не лишним

На этом у меня всё. Спасибо за внимание. Удачи!

в 21:56 Изменить сообщение

У Вас в браузере заблокирован 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:

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

С задачей очистки 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-структуры документа, в сети разгораются настоящие холивары. Вот, например, на оверфлоу. Невинный с первого взгляда