nip
Guest
Умный парсинг "\n" => "<br>" мой вариант, альтернатива, ваши мнения и п
Долго искал разные варианты умного преобразования текста (что типа обработчика на livejournal.com).
Проблема в том, что нужно проставлять переносы только в тех местах где нет спецальных тегов, напрмер между "<" и ">", "<tr>" и "<td>" и прочее проставлять низя - заколбасит.
Собственно что пидумал - задать в массиве условия входа и выхода из игнорного блока (выходов - может быт несколько), собственно алгоритм таков:
1. перебирается посимвольно строка и проверяется вход в игнорный блок. Если вошли то задаем номер игнорного блока (что бы потом можно было выйти)
2. Если не вошли в игнорный блок то делаем собсно замены имволов "\n"
3. На каждом симоволе делаем проверку на выход из игнорного блока (перебираем несколько выриантов выхода по выбору).
Собственно, чего мне не нравится:
1. Слишоком долго выполняется проверка входа и выхода.
2. В регулярных выражениях описать не смог (слишом много уловий)
3. Будет работать правильно только в случае правильного html
Если кто занимался подобной порнографией отзовитесь, буду рад любым советам и примерам.
Прилагаю собственный вариант:
Долго искал разные варианты умного преобразования текста (что типа обработчика на livejournal.com).
Проблема в том, что нужно проставлять переносы только в тех местах где нет спецальных тегов, напрмер между "<" и ">", "<tr>" и "<td>" и прочее проставлять низя - заколбасит.
Собственно что пидумал - задать в массиве условия входа и выхода из игнорного блока (выходов - может быт несколько), собственно алгоритм таков:
1. перебирается посимвольно строка и проверяется вход в игнорный блок. Если вошли то задаем номер игнорного блока (что бы потом можно было выйти)
2. Если не вошли в игнорный блок то делаем собсно замены имволов "\n"
3. На каждом симоволе делаем проверку на выход из игнорного блока (перебираем несколько выриантов выхода по выбору).
Собственно, чего мне не нравится:
1. Слишоком долго выполняется проверка входа и выхода.
2. В регулярных выражениях описать не смог (слишом много уловий)
3. Будет работать правильно только в случае правильного html

Если кто занимался подобной порнографией отзовитесь, буду рад любым советам и примерам.
Прилагаю собственный вариант:
PHP:
# Переменная которую будем обрабатывать (как видите, куча подводных камней)
$in = "
12
3
4
1
<table
border=1><tr
>
<td
>123
321
</td>
<td
>123
321
</td>
</tr>
<tr
>
<td
>123
<u>321</u>
</td>
<td
>123
321
</td>
</tr>
</table>
<textarea>1
2</textarea>
";
echo smart_nl2br($in);
# Собственно функция простановки переносов
function smart_nl2br($in){
# Массив игнорируемых блоков (первый элемент строки - условие входа, остальные - условия выхода)
$ignor_it[1][]= "<"; $ignor_it[1][]= ">";
$ignor_it[2][]= "<table"; $ignor_it[2][]= "</table>"; $ignor_it[2][]= "<td";
$ignor_it[3][]= "<td"; $ignor_it[3][]= ">";
$ignor_it[4][]= "<tr"; $ignor_it[4][]= "<td";
$ignor_it[5][]= "</td"; $ignor_it[5][]= "</tr";
$ignor_it[6][]= "</tr"; $ignor_it[6][]= "<tr"; $ignor_it[6][]= "</table";
$ignor_it[7][]= "<textarea"; $ignor_it[7][]= "</textarea";
# Убираем r-ки что бы не мешались
$in = str_replace("\r","",$in);
# Обнуляем индикатор игнорности текущего блока, по совместительству номер типа игнорируемого блока
$ignor = 0;
# Начинаем посимвольный перебор
for ($i=0;$i<strlen($in);$i++){
# Проверка на вход в игнорный блок (ищем подходящий игнорный блок)
for ($k=1;$k<=count($ignor_it);$k++){
#echo substr($in,$i,strlen($ignor_it[$k][0]));
if (substr($in,$i,strlen($ignor_it[$k][0])) == $ignor_it[$k][0]) {
$ignor = $k;
}
}
if ($ignor>0){
# Проверка на выход из игнорного блока (перебор завершений)
for ($k=1;$k<count($ignor_it[$ignor]);$k++){
if (substr($in,$i,strlen($ignor_it[$ignor][$k])) == $ignor_it[$ignor][$k]) {
$ignor = 0;
}
}
}
if ($ignor==0){
# Добавляем переносы
if ($in[$i]=="\n"){
$in = substr($in,0,$i)."<br>\n".substr($in,$i+1,strlen($in)-$i);
$i = $i + strlen("<br>\n");
}
}
}
return $in;
}