Преобразование спец.символов в HTML-сущности в части документа

версия для печати

В HTML некоторые символы имеют специальное значение и для сохранения своего значения должны быть преобразованы в HTML-сущности. Начиная с 3-ей версии в PHP для этого есть функция - htmlspecialchars(). Работает отлично, но проблема в том, что на преобразует весь html-документ. У меня возникла необходимость преобразования спец. символов только в части документа, а именно сохранение "внешнего вида" угловых скобок в примерах кода на html-страницах.

Ручной вариант: в исходном тексте документа в примерах писать '<' или '>' вместо угловых скобок. Наверняка есть какие-нибудь инструменты для таких замен, может даже online-сервисы. Вот простой рабочий пример сервиса:

Online-преобразование спец.символов в HTML-сущности во всем тексте



Ручная обработка меня не улыбает в силу субъективных причин. Вообщем я сочинил php-функцию, даже две :) Точнее, на другой день придумал второй вариант. Здесь приведу коды обоих вариантов. Если у вас есть идеи лучше, подскажите, буду признателен.

Итак, постановка задачи: заменить спец. символы на html-сущности только внутри тега <code> ... </code>, учитывая что блоков "code" в документе может быть несколько.

Вариант 1
function keep_tags_in_code($text)
{
//Выбрать все блоки тега <code> ... </code>.
//Массив заполнять наборами вхождений. Так же в массив писать позицию в исходной строке, с которой найдено совпадение.
preg_match_all('#<code>(.*)</code>#Us', $text, $match, PREG_SET_ORDER + PREG_OFFSET_CAPTURE);
$shift=0; //Учитываем сдвиг в этой переменной.
foreach($match as $v)
{
    $code=$v[1][0];                                                //Текст внутри тега <code>
    $code=str_replace(array('<','>'), array('&lt;','&gt;'), $code);//Замена угловых скобок на HTML-сущности
    $old_len=strlen($v[1][0]);                                     //Длина старого текста в <code> ... </code>
    $text=substr_replace($text, $code, $v[1][1]+$shift, $old_len); //Замена старого текста новым.
    $shift+=strlen($code)-$old_len;                                //Расчет сдвига.
}
return $text;
}

Принцип такой: регулярным выражением выбираем все куски кода из html-текста. Заменяем в них скобки на '&lt;' или '&gt;'. Потом в основном тексте заменяем старый код новым. Учитываем смещение в основном тексте, которое получается в результате замены на бОльшее количество символов. В дальнейших заменах в тексте сдвигаемся на это значение. В строке 10 можно использовать упомянутую ранее функцию PHP:

10|    $code=htmlspecialchars($code);

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

Вариант 2
function keep_tags_in_code($text)
{
   $ptrn_lt='#(<code>[^<]*)<(?!/code>)(.*</code>)#Us';
   $ptrn_gt='#(<code>[^>]*)(?<!</code)>(.*</code>)#Us';
   //Пока будут найдены '<' или '>' внутри тега '<code>', заменяем их на html-сущности 
   while (preg_match($ptrn_lt,$text)) $text=preg_replace($ptrn_lt,'$1&lt;$2',$text);
   while (preg_match($ptrn_gt,$text)) $text=preg_replace($ptrn_gt,'$1&gt;$2',$text);
   return $text;
}

Здесь сложнее в понимании. Идея: регулярным выражением описываем ситуацию, когда внутри парного тега <code> есть угловая скобка. Пока есть такой текст, производим замену. Конечно, перебор в цикле работает долго, но я не смог придумать еще проще и быстрее.

Пример работы функций

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

<html>
<head><title>Тест. Частичное преобразование спец.символов</title></head>
<body>
<b>Что-то до блоков с примерами кода..</b>
<code>
    <h4>Первый пример.</h4>
    <font color='red'>Теги не работают, хотя именно так прописаны в исходнике</font>
</code>
<b>..что-то между..</b>
<code>
    <h4>Второй пример.</h4>
    <font color='green'>и здесь спец.символы преобразованы в сущности описанной функцией.</font>
</code>
<b>и в после всего.</b>
</body></html>

Подаем текст в функцию. В браузерe получим:

Что-то до блоков с примерами кода..
<h4> Первый пример.</h4>
<font color='red'> Теги не работают, хотя именно так прописаны в исходнике</font>
..что-то между..
<h4> Второй пример.</h4>
<font color='green'> и здесь спец.символы преобразованы в сущности описанной функцией.</font>
и в после всего.
[1oo%, EoF]

Понравилась статья? Расскажите о ней друзьям:

Метки: PHP, кодинг

Комментарии
Для работы модуля комментариев включите javaScript


Показать/скрыть правила
Имя
[i] [b] [u] [s] [url]
:-) ;-) :D *lol* 8-) :-* :-| :-( *cry* :o :-? *unsure* *oops* :-x *shocked* *zzz* :P *evil*

Осталось 1000 символов.
Код защиты от спама Обновить код
Каждый комментарий проходит ручную модерацию. 100% фильтрация спама.
Продвижение
Время
Метки