Русский English Deutsch Українська Қазақша

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

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

Вы не вошли.

#1 2010-11-25 03: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. Единственный замеченный мною недостаток это, то что функция обрезает текст без учета читабельности. И вполне способна  разорвать слово или строку... Лечить это мне пока лень) Хотите сделайте сами :)

Отредактировано Necronominicon (2010-11-25 03:49:46)


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

Вне форума

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

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

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

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

Вне форума

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

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

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

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


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

Вне форума

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

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

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

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

Вне форума

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

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

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

Trashcka, :D


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

Вне форума

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

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

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

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

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

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

Вне форума

#7 2010-11-25 08: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 08:41:02)


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

Вне форума

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

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

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

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

Вне форума

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

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

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

Wolverine, его не будет :D


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

Вне форума

Сейчас в этой теме пользователей: 0, гостей: 1
[Bot] ClaudeBot

Подвал форума

Под управлением FluxBB 1.5.11
Модифицировал Visman

[ Сгенерировано за 0.015 сек, 7 запросов выполнено - Использовано памяти: 573.95 Кбайт (Пик: 595.16 Кбайт) ]