Корректно обрезать текст

Spear

почемучка
Корректно обрезать текст

Здравствуйте,
у меня возникла такая проблема:
есть текст, который выводится пользователю. Выводится не полностью а только первые 300 символов. Потом он обрезается и ставится троеточие "...".

проблема в том что иногда при обрезании текста убирается незакрытый тег..
получается чтото вроде:

"text text <a href="blablabla..."
подскажите пожалуйста, как мне решить эту проблему? я думаю что некоторые сталкивались с такой же проблемой.
Единственное что - это нужно оставить теги. Всмысле делать полностью strip_tags нельзя.
 

sayber

Новичок
делить по словам, некрасиво получится, если слово будет незакончено
 

440hz

php.ru
Re: Корректно обрезать текст

Автор оригинала: Spear
Здравствуйте,
у меня возникла такая проблема:
есть текст, который выводится пользователю.
завести еще одно поле в таблице именно для этого и выводить его ...

и почитать вот это
 

Spear

почемучка
sayber
если порежется слово - ничего страшного.

440hz
это, конечно, тоже вариант. Но очень неудонбый и плохой.

Я уверен что как-йто способ есть для решения этой задачи, так как подобное видел на многих сайтах.
там явно видно что это не отдельно поле в БД, так как местами режутся сами слова,
но в то же время - там всегда корректно отображаются теги. никогда не разрываются.

-~{}~ 21.09.05 13:28:

почитать вот это
мда... именно то что мне нужно - сидеть и перебирать фиг-знает сколько записей в базе, делать им уменьшенные дублика ты и так далее. Спасибо. Когда мне понадобится ещё один ответ _не_по_темЕ_ - я к вам обращусь.
 

440hz

php.ru
Автор оригинала: Spear
но в то же время - там всегда корректно отображаются теги. никогда не разрываются.
регекспом вытаскиваешь текст из тегов. его режешь. вставляешь обратно.
 

Spear

почемучка
хм.. а какэ то примерно будет выглядеть? всмысле не код а действия.
Например текст будет обрезаться на таком моменте (жирным - место обреза)

some text <a href="link">page</a>

тут нужен или гипер-умный регексп (а я с регекспами вообще не очень.. только примитив)..
или другой способ.
У меня что-то в голове крутится по поводу:
вычисления точки обреза текста,
потом смотрим - нет ли левее от этой точки открытого тега. Если есть - убираем тег (открытый).
Только это все "условно".
Как это будет на практике - не знаю даже..

-~{}~ 21.09.05 13:41:

АГА! Наконец-то! Ура-ура :) Я-таки нашел на том сайте (на котром я думал супер умно вычисляются теги) что все-таки там в одном месте обрезался тег :)

Тогда такой вопросик (это уже полегче:))
как вырезать (желательно по-проще) из текста все теги кроме ntujd <b> и <u>?
 

Andreika

"PHP for nubies" reader
Spear
как вырезать (желательно по-проще) из текста все теги кроме ntujd <b> и <u>?

strip_tags )

а что если
$r = preg_split('/(<[^>]*>)/im',$text,-1,PREG_SPLIT_DELIM_CAPTURE);
получится массив из текста и тэгов.. потом проходим по массиву, суммируем длину текста.. лишний текст в элементе обрезаем, а из остальной части массива берем только нужные закрывающие тэги
 

Spear

почемучка
Andreika
звучит сложно и, скорее всего, верно.
Но вот тут в чем загвоздка - (повторюсь, извините) - я с регексспами не очень лажу. У меня с ними лажа :) Навряд ли я смогу реализовать то, что вы предложили ;(
 

440hz

php.ru
Автор оригинала: Andreika
получится массив из текста и тэгов.. потом проходим по массиву, суммируем длину текста.. лишний текст в элементе обрезаем, а из остальной части массива берем только нужные закрывающие тэги
об том и речь. проходим по массиву. собираем все в одну перемнную и при этом суммируем длину текста. если превышает 300 обрезаем по последнего пробелла.

вот что делать с открытыми тегами? 8)

-~{}~ 21.09.05 13:53:

Автор оригинала: Spear
У меня с ними лажа :) Навряд ли я смогу реализовать то, что вы предложили ;(
ща тебе Фанат все популярно объяснит зачем тут люди ваще общаются ...
 

Andreika

"PHP for nubies" reader
PHP:
  $text= 'a tset21 gfghjdfhg gfdhughruitg <font color=red>gfgnjfk</font>dfsd fhdsfuheiu <b>fdfn</b> fdsjirhfeiohfiohsd<a href="dasds">dsadsdf</a>';

  $tags = array(); // массив, в который записываем кол-во открытых тэгов

  $r = preg_split('/(<[^>]*>)/im',$text,-1,PREG_SPLIT_DELIM_CAPTURE);

  $c =0 ; // счетчик длины строки
  $mx = 57; // макс. длина текста
  $cw = true; // достигли ли макс. - можно заменить на ($mx>$c)
  $res = ''; // результат

  foreach ($r as $w) {
    
     // если тэг
     if (preg_match('/<(\/?)([a-z]+)\s*[^>]*>/ims',$w,$m)) {
        print_r($m);
        if ($m[1]!='/') { // открывающий

           if ($cw){ // если еще не макс., то пишем, добавляем в счетчик тэгов
            $tags[strtolower($m[2])]++;
            $res.=$w;
           }
        } else { // закрывыющий тэг

 // уменьшаем счетчик , если есть такой открытый тэг - пишем
           if ($tags[strtolower($m[2])]>0) {
              $res.=$w;
           }
           $tags[strtolower($m[2])]--;
        }
     } else { // текст

      if ($cw) { 
       $len = strlen($w); // длина текста
        if ($len+$c>$mx) { // достигли?
   // обрезаем, добавляем ...
           $res.=substr($w,0,$mx-$c)."...";
           $cw = false; 
        }else {

           $res.=$w;
           $c+=$len;
        }
      }
     }

     print_r($tags);
  }

  echo "\n<BR>$res\n<BR>$text";
в оригинале в $r = preg_split('/(<[^>]*>)/im',$text пробелов нет.. но в форуме появляются %)
 

Spear

почемучка
ого!
Спасибо большое.
езаю, ещё не проверял.. но всеравно спасибо - за уделенное внимание и потраченное время
 
Сверху