Forum Webscript.Ru

Программирование => PHP => Тема начата: FreeSpace от 06 Февраля 2004, 01:39:31

Название: Чистка HTML
Отправлено: FreeSpace от 06 Февраля 2004, 01:39:31
Я написал функцию, которая позволяет чистить HTML от вайтспейсов.
Дабы избежать флейма, сразу оговорюсь:
Да, я знаю, что изобрел велосипед.
Да, я знаю, что существует огромное количество программ, которые делают это быстрее и эффективнее, например Tidy (http://tidy.sourceforge.net).
И я советую каждому пользоваться именно этой программой, а не моей самописной функцией :)
А взялся я за написание этой функции с одной целью - получить дополнительный опыт, который лишним никогда не бывает.
А теперь я бы хотел узнать ваше мнение - как по-вашему можно оптимизировать этот алгоритм? Мне, например, самому не нравится использование случайной строки для подстановки тегов, но ничего лучше я пока не придумал.
Кроме того, может я какие-то теги забыл, в которых нужно было сохранять форматирование?
function trim_whitespaces ($text)
{
// Убираем многострочные теги
$tags = array();
$tags[\'textarea\']   = $this->tag_replace(\'textarea\', $text);
$tags[\'scripts\']    = $this->tag_replace(\'script\', $text);
$tags[\'style\']      = $this->tag_replace(\'style\', $text);
$tags[\'pre\']        = $this->tag_replace(\'pre\', $text);
$tags[\'code\']       = $this->tag_replace(\'code\', $text);

$text = preg_replace (\'~(\\\\>)(\\\\s*)(\\\\<)~\', \'\\\\1\\\\3\', $text);
$text = preg_replace (\'~(\\\\s+)~\', \' \', $text);

// Восстанавливаем многострочные теги
foreach ($tags as $tag)
{
$text = str_replace(array_keys($tag), $tag, $text);
}

return $text;
}

function tag_replace ($tag_name, &$text)
{
if (!stristr($text, \'<\'.$tag_name))
{
return array();
}

// Нам нужно получить уникальную строку, которая НЕ встречается в обрабатываемом тексте
do
{
$uniqid = substr(md5(uniqid(rand(), TRUE)), 0, 5);
}
while(strstr($text, $uniqid));

// Ищем все необходимые теги
$matches = array();
preg_match_all(\'~(<\'.preg_quote($tag_name).\').*()~isU\', $text, $matches);
$matches = $matches[0];

// Заменяем теги на безопасну строку
$tags = array();
foreach ($matches as $k => $tag)
{
// Выглядит примерно как "<[[textarea_f7a53: 0]]/>" , "<[[textarea_f7a53: 1]]/>" и так далее для каждого тега.
$key = \'<[[\'.$tag_name.\'_\'.$uniqid.\': \'.$k.\']]/>\';
$tags[$key] = $tag;
$text = str_replace($tag, $key, $text);
}

return $tags;
}
Название: Чистка HTML
Отправлено: Меняздесьдавнонет от 06 Февраля 2004, 01:45:16
мне кажется, что это можно сделать одним регом.
но я не возьмусь.
Название: Чистка HTML
Отправлено: гоша от 06 Февраля 2004, 12:00:51
> не нравится использование случайной строки для подстановки тегов, но ничего лучше я пока не придумал

можно так:

$tags="pre|script|textarea|code|xmp|style";

$text=preg_replace_callback(
"~<($tags)>.*?~si", "addToBuf", $text);

function addToBuf($match)
{
global $buf;

$buf[]=$match[0];
return "\\x01".(count($buf)-1);
}

т.е. куски не подлежащие обработке заносятся в массив и заменяются на  \\x01номер.

После обработки вставляем их назад, например так:

preg_replace("~\\x01(\\d+)~e","\\$buf[$1]", $text)



По поводу твоего кода -- я бы тебе советовал никогда не писать U (равно как A и D).
Название: Чистка HTML
Отправлено: Yukko от 06 Февраля 2004, 12:47:03
Цитировать
гоша:
я бы тебе советовал никогда не писать U (равно как A и D).

мы тут, кажется, не в бирюльки играем, и топик этот читают люди, которым не надо основы разжевывать и говорить, что, мол, напиши сначала вот так, потому что ТАК ПРАВИЛЬНО, а потом мы тебе объясним...
Поэтому писать поверьте мне НАСЛОВО не надо. Если можешь объяснить почему ты не советовал, то тогда объясни, если не можешь, не пиши вообще!
Название: Чистка HTML
Отправлено: гоша от 06 Февраля 2004, 13:04:35
То есть разжевать всё-таки надо? Ок, разжую.

1) эти модификаторы несовместимы с perl и другими языками. Поэтому они делают ваши шаблоны менее переносимыми. Пример: валидация поля формы одним шаблоном на клиенте (яваскрипт) и на сервере (пхп).

2) эти модификаторы затрудняют чтение и отладку кода, потому что изменяют значения метасимволов. Программирование есть борьба с хаосом, и одно из первых средств -- называть одинаковые вещи одинаковыми именами. Если мы решили, что "?" обозначает non-greedy, то пусть так будет всегда, без исключений. Жизнь и без того достаточно сложна.

Хватит?
Название: Чистка HTML
Отправлено: Макс от 06 Февраля 2004, 13:29:52
гоша
 В перле в регах есть куча примочек недоступных в других языках. Ты перл-программерам тоже посоветуешь не использовать все возможности регекспов ?
Название: Чистка HTML
Отправлено: гоша от 06 Февраля 2004, 13:37:33
Не устраивайте флейм на ровном месте.
Прочтите мое сообщение еще раз.
Если что-то непонятно -- спрашивайте.
Название: Чистка HTML
Отправлено: Yukko от 06 Февраля 2004, 14:26:02
Милый гоша тебе ORDER BY в SQL запросах не нарушает естественный вывод данных из таблицы? Это, считай, тоже модификатор.
А с командной строки, когда команды в юниксе набираешь, тебе ничего не мешает? никакой модификтор не вносит неясности в жизни программиста?
Почему-то тебя не смущает неперносимость программного кода PHP в Perl методом copy-paste...

Модификаторы нужно знать и пользоваться ими!

Цитировать
эти модификаторы несовместимы с perl и другими языками.
если ты такой шустрый, то пользуйся Posix стандартом в написании РВ, ты завоешь белугой, потому что половина фич, которые работают в Perl и PHP тебе будут недоступны.

Цитировать
Не устраивайте флейм на ровном месте.
Прочтите мое сообщение еще раз.
Если что-то непонятно -- спрашивайте.

только вот не надо нас равнять, хорошо?
Я лично полный идиот в регулярных выражениях, поэтому спрашиваю:
Почему нельзя использовать эти модификторы?
Меня абсолютно не устраивает довод, что они вносят ХАОС в программный код!
Я ложил на совместимость написанных РВ с Perl\'ом, Javascript\'ом, а так же bash, tcl, python, VB (особенно VB!!!)
Название: Чистка HTML
Отправлено: гоша от 06 Февраля 2004, 14:34:37
Yukko

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

Кроме того, ты глуп.
Название: Чистка HTML
Отправлено: Макс от 06 Февраля 2004, 14:40:02
гоша
судя по твое фразе
Цитировать
гоша:
Хватит?

у тебя еще есть аргументы в пользу неиспользования модификторов \\U и тому подобных.
Расскажи, так как приведенные тобой выше аргументы неубедительны
Название: Чистка HTML
Отправлено: Yukko от 06 Февраля 2004, 14:46:05
1. Я задал нормальные вопросы, ты ни на один не дал вразумительного ответа.
2. Насчет моей глупости мог бы и смолчать...
3. Вот Юкко урод, его гоша в своих 16-ти постах так задел, что после этого Юкко начали двигать личные чувства!
4. У тебя еще не такой большой авторитет, чтобы просто сказать:
верьте мне, в моих словах истина!!!
Поэтому я повторяю вопрос, тот же самый заметь, который тебе задал Макс:
Какие еще есть аргументы по поводу неиспользования модификаторов у тебя есть, кроме внесения хаоса и анархии в исходный код программы, условия и список языков, на совместимость с которыми я ложил, остаются прежними.
Название: Чистка HTML
Отправлено: FreeSpace от 06 Февраля 2004, 19:22:42
гоша
Спасибо за идею.
Я сам склонялся к твоему подходу, но просто хотелось быть уверенным, что код будет работать даже при условии, что в тексте могут попадаться бинарные данные... мало ли, у кого какие ручки шаловливые :)

По поводу модификатора U - сам по себе код настолько завязан на конкретном языке, что добиваться какой-то переносимости нет смысла.
Да и интересовал меня сам алгоритм, а такие мелочи как использование U или ? - ИМХО второстепенны.