Next Generation CMS :: Форум поддержки

Заинтересовала наша система? Тогда этот форум для Вас!

Вы не зашли.

#1 2010-11-25 04:47:15

Necronominicon
Участник
Откуда Луганск, Украина
Зарегистрирован: 2010-10-31
Сообщений: 102
Рейтинг :   
Сайт

Обрезка текста без потери структуры тегов и bb кодов

Предисловие:
Когда я реализовывал поиск по статике, то столкнулся с проблемой, что короткой части в статике нет, поэтому в таблицу результатов поиска скрипт выводил абсолютно весь контент страницы. Может это и не критично, если у Вас на странице по паре предложений, но на моих в среднем по 5-6 страниц А4. Значит статику следовало урезать. Передо мной было два варианта:
- вырезать теги и обрезать чистый текст;
- сохранить теги и попытаться обрезать текст вместе с ними. Кто сталкивался с таким знает, что сделать это сложно. Подводных камней масса. Но я рад, что мне удалось это)
Привожу на Ваш суд функцию, которая позволила мне корректно обрезать текст, сохраняя структуру тегов:

function htmlSubstr($html, $length)
{
    $out = '';
    $arr = preg_split('/(<.+?>|&#?\\w+;)/s', $html, -1, PREG_SPLIT_DELIM_CAPTURE);
    $tagStack = array();

    for($i = 0, $l = 0; $i < count($arr); $i++) {
        if( $i & 1 ) {
            if( substr($arr[$i], 0, 2) == '</' or substr($arr[$i], 0, 2) == '[/') {
                array_pop($tagStack);
            } elseif( $arr[$i][0] == '&' ) {
                $l++;
            } elseif( substr($arr[$i], -2) != '/>' or substr($arr[$i], -2) != '/]') {
                array_push($tagStack, $arr[$i]);
            }

            $out .= $arr[$i];
        } elseif( substr($arr[$i], -2) != '/>' ) {
            if( ($l += strlen($arr[$i])) >= $length ) {
                $out .= substr($arr[$i], 0, $length - $l + strlen($arr[$i]));
                break;
            } else {
                $out .= $arr[$i];
            }
        }
    }

    while( ($tag = array_pop($tagStack)) !== NULL ) {
        $out .= '</' . strtok(substr($tag, 1), " \t>") . '>';
    }

    return $out;
}

$s =<<<HTML
<h6><a href='' name='name1'>Экспозиция в зале полиции</a></h6>
[p]Экспозиция музея начинается с зала истории Луганской полиции. Появление первых представителей правоохранительных органов в нашем крае напрямую связано со строительством Луганского литейно-пушечного завода в 1795 г. С высочайшим утверждением 3 сентября 1882 г. Положения о возведении поселка литейного завода в степень уездного города в Луганске учреждается полицейская команда в составе 20 человек. [/p]<center><table><tr><td>[url=http://localhost/lugmia/museum/uploads/images/default/d24d1801bd.jpg" onclick="return hs.expand (this)"  class="highslide][img="http://localhost/lugmia/museum/uploads/images/default/thumb/d24d1801bd.jpg" class="nimg" border="0" align="left"]d24d1801bd.jpg (82.71 Kb)[/img][/url]</td><td>[url=http://localhost/lugmia/museum/uploads/images/default/c036e00f50.jpg" onclick="return hs.expand (this)"  class="highslide][img="http://localhost/lugmia/museum/uploads/images/default/thumb/c036e00f50.jpg" class="nimg" border="0" align="left"]c036e00f50.jpg (140.64 Kb)[/img][/url]</td><td>[url=http://localhost/lugmia/museum/uploads/images/default/db8d1a3570.jpg" onclick="return hs.expand (this)"  class="highslide][img="http://localhost/lugmia/museum/uploads/images/default/thumb/db8d1a3570.jpg" class="nimg" border="0" align="left"]db8d1a3570.jpg (159.67 Kb)[/img][/url]</td><td>[url=http://localhost/lugmia/museum/uploads/images/default/239cf3b6bb.jpg" onclick="return hs.expand (this)"  class="highslide][img="http://localhost/lugmia/museum/uploads/images/default/thumb/239cf3b6bb.jpg" class="nimg" border="0" align="left"]239cf3b6bb.jpg (96.35 Kb)[/img][/url]</td></tr></table></center>
[p]К началу ХХ века в Луганске уже функционировало 4 городских полицейских участка, а также Славяносербское уездное управление, находящееся на Банковской улице, арестный дом, рассчитанный на 24 человека, тюремный замок. Городскому полицейскому управлению подчинялись участковые приставы, полицейские, околоточные надзиратели, городовые. Расчет количества полицейских чинов в городах велся по норме – не менее одного городового на 500 жителей. Вступая в должность, полицейские давали клятвенное обещание, полный текст которого, как и места размещения учреждений полиции, можно увидеть в зале музея. Музей располагает копиями полицейских рапортов, донесений, сообщений «филеров» (специальных агентов жандармерии, осуществляющих надзор за политически неблагонадежными гражданами), фрагменты уголовного дела на беглых рабочих Луганского литейного завода, датированных 1807 г. и многие другие.[/p]
<center><table><tr></tr></table></center>
[p]В феврале 1905 года в Луганске состоялась первая всеобщая забастовка рабочих, тем самым назрела необходимость создания в Луганске жандармского управления, которое было размещено в Каменном Броде. В зале можно ознакомиться с материалами о знаменитых деятелях революционного движения, отбывавших наказание в  тюремном замке. Г.И. Петровский, К.Е. Ворошилов, Я. Моргенштейн и многие другие были узниками камер Луганской тюрьмы. Здесь же представлены распорядок дня и прогулок, расписание кушаний для политзаключенных, которые они могли заказать за свой счет.[/p]
[p]На К.Е.Ворошилова партией большевиков была возложена обязанность создания и обучения боевых рабочих дружин. Опираясь на них, ставших прообразом Красной Гвардии, большевики устанавливали и охраняли революционный порядок в поселках и городах уезда.[/p]
<div class='next'><a href='http://localhost/lugmia/museum/static/main-page-of-lugansk-police-museum.html' title='Перейти к главной странице'>Перейти к главной странице</a> | <a href='http://localhost/lugmia/museum/static/karta_saita.html' title='Карта сайта'>Карта сайта</a> | <a href='http://localhost/lugmia/museum/static/zal-of-police-history-of-lugansk-police-museum.html' title='Перейти к залу истории милиции'>Перейти к залу истории милиции</a></div>
HTML;
$aa = htmlSubstr($s, 2500);

echo $aa;
echo '<br>----------------<br>'.strlen(strip_tags($aa));

Думаю, что кому-нибудь она сможет пригодиться

P.S. Единственный замеченный мною недостаток это, то что функция обрезает текст без учета читабельности. И вполне способна  разорвать слово или строку... Лечить это мне пока лень) Хотите сделайте сами smile

Изменено Necronominicon (2010-11-25 04:49:46)


Бог умер © Ницше
Ницше умер © Бог

Не в сети

#2 2010-11-25 04:54:42

Trashcka
Участник
Откуда КиевГрад
Зарегистрирован: 2008-12-04
Сообщений: 1,487
Рейтинг :   73 

Re: Обрезка текста без потери структуры тегов и bb кодов

Necronominicon, тут еще вариант для полных новостей, если надо.

Не в сети

#3 2010-11-25 05:00:39

Necronominicon
Участник
Откуда Луганск, Украина
Зарегистрирован: 2010-10-31
Сообщений: 102
Рейтинг :   
Сайт

Re: Обрезка текста без потери структуры тегов и bb кодов

Trashcka, мне уже не надо smile Но вот скажи, приведенный вариант в статье корректно обрезает все теги?


Бог умер © Ницше
Ницше умер © Бог

Не в сети

#4 2010-11-25 05:05:52

Trashcka
Участник
Откуда КиевГрад
Зарегистрирован: 2008-12-04
Сообщений: 1,487
Рейтинг :   73 

Re: Обрезка текста без потери структуры тегов и bb кодов

Necronominicon, а я не обращала внимания big_smile big_smile

Не в сети

#5 2010-11-25 05:13:17

Necronominicon
Участник
Откуда Луганск, Украина
Зарегистрирован: 2010-10-31
Сообщений: 102
Рейтинг :   
Сайт

Re: Обрезка текста без потери структуры тегов и bb кодов

Trashcka, big_smile


Бог умер © Ницше
Ницше умер © Бог

Не в сети

#6 2010-11-25 09:09:27

vitaly
Администратор
Откуда Россия
Зарегистрирован: 2008-10-08
Сообщений: 2,823
Рейтинг :   118 

Re: Обрезка текста без потери структуры тегов и bb кодов

Necronominicon, у тебя функция не грохнется на такой вот конструкции?

<div style="<tr><td><table>">Hello!</div>

А вообще в классе parse (/engine/includes/classes/parse.php), который живёт в глобальной переменной $parse есть функция truncateHTML.
Она делает тоже самое smile

Не в сети

#7 2010-11-25 09:35:48

Necronominicon
Участник
Откуда Луганск, Украина
Зарегистрирован: 2010-10-31
Сообщений: 102
Рейтинг :   
Сайт

Re: Обрезка текста без потери структуры тегов и bb кодов

vitaly, big_smile
Сам попробуй wink
Выведет (при 1000 знаков)

Hello! в браузере

и

<div style="<tr><td><table>">Hello!</div></td></div>

В коде
А при одном:

H в браузере

и

<div style="<tr><td><table>">H</div></td></div>

в коде

Изменено Necronominicon (2010-11-25 09:41:02)


Бог умер © Ницше
Ницше умер © Бог

Не в сети

#8 2010-11-25 09:37:37

Wolverine
Модератор
Откуда Домодедово
Зарегистрирован: 2008-10-13
Сообщений: 3,538
Рейтинг :   160 
Сайт

Re: Обрезка текста без потери структуры тегов и bb кодов

Я все жду поста "Оцените CMS" ))

Не в сети

#9 2010-11-25 09:40:28

Necronominicon
Участник
Откуда Луганск, Украина
Зарегистрирован: 2010-10-31
Сообщений: 102
Рейтинг :   
Сайт

Re: Обрезка текста без потери структуры тегов и bb кодов

Wolverine, его не будет big_smile


Бог умер © Ницше
Ницше умер © Бог

Не в сети

Подвал раздела

Работает на FluxBB