Xpoint
   [напомнить пароль]

Обрезать текст до n символов, тэги при этом не считая, но сохраняя их

Метки: [без меток]
2010-02-11 17:36:20 [обр] Agar -Agar(0/68)[досье]

Никак не догадаюсь, как такое сделать. Нужно подготовить текст в сокращенном варианте. Текст может содержать и разметку HTML. Тэги при этом нужно оставить. Т.е. нужно считать все символы, но только если они не внутри описания тэгов (сами угловые скобки тэгов тоже не считаем), и на энном символе остановиться, выведя все что было до этого вместе с тэгами, а остальное заменить троеточием. Сразу скажу, что тэги потом посчитаю отдельно, и для незакрытых пропишу в конце строки закрывающие тэги.

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

... Бред какой-то. Может, это все одной регуляркой можно сделать?

спустя 50 минут [обр] Прокаев2(0/35)[досье]
вам скорее поможет автомат ;) стековый
спустя 5 минут [обр] Прокаев2(0/35)[досье]
если нет вложенных тэгов,
то достаточно цикла по символам строки + счетчик видимых символов
(естественно в выходной поток тэги, не увеличивая этот счетчик)
спустя 18 минут [обр] Евгений Седов aka KPbIC(0/187)[досье]
Agar -Agar[досье] Не думали отделить контент от разметки на архитектурном уровне?
спустя 5 часов [обр] Agar -Agar(0/68)[досье]
Честно говоря, не понял, что Вы имели в виду, т.к. знаний у меня маловато. Пошел по сложному пути и нагородил вот такой ужас. Подробно расписал, чтобы потом не заблудиться в коде. Все работает как надо, но подозреваю, что регуляркой можно было сделать то же самое в одну строку. Закрывать незакрытые тэги буду потом.
#!/usr/bin/perl -w
print "Content-type: text/html\n";
print "\n";


$otz = "<a href=\"hjj\">1<b>2<i>3</i>45</a><i>6</i><a style=\"color:ff0000\">7</a>890</b> 234 <i>6</i>789<b>012 45 6</b>7890";

print "$otz";

$otz_klein = "$otz";

my @massiv_tegov;#--в этот массив буду складывать все тэги

$otz_klein =~ s/<(.*?)>/&obrabotka_tegov($1)/ge;#--беру все что между < и > и посылаю на обработку в подпрограмму obrabotka_tegov


      sub obrabotka_tegov
      {
      my $teg = shift;

      push (@massiv_tegov,$teg);#заношу тег в массив

      $teg = "<>";#--заместо него вставлю эмулятор из двух символов
      return $teg;
      }







$skolko_nuschno_simvolov = 10;#--в этой переменной окончательно буду формировать, сколько нужно взять символов без тегов


for($i = 0; $i< 100;$i++)

{

   $kopija_otz_klein = $otz_klein;


   $kopija_otz_klein =~ s!(.{$skolko_nuschno_simvolov}).*!$1!;#--читаю символы и после нужного обрезаю

   $skolko_tegov = 0;#--ставлю по умолчанию сколько тегов

   $kopija_otz_klein =~ s/</++$skolko_tegov;/ge;#--увеличиваю счетчик на единицу



   if ($skolko_tegov > 0)
      {
      $skolko_tegov = $skolko_tegov*2+10;#--прибавляю 10 и умножаю на 2 по количеству символов эмуляторов
      }
      else
         {
         $skolko_nuschno_simvolov = 10;
         last;#--прерываю цикл, если в тексте указанной длины вообще нет тэгов
         }


#--прохожу еще раз, если не вышел из цикла, чтобы проверить, не будет ли еще тегов после прибавки

   $kopija_otz_klein = $otz_klein;

   $kopija_otz_klein =~ s!(.{$skolko_tegov}).*!$1!;#--читаю символы и после нужного обрезаю

   $skolko_tegov_2 = 0;#--ставлю по умолчанию сколько тегов

   $kopija_otz_klein =~ s/</++$skolko_tegov_2;/ge;#--увеличиваю счетчик на единицу

   $skolko_nuschno_simvolov = $skolko_tegov_2*2+10;


   if ($skolko_tegov == $skolko_nuschno_simvolov)
      {
         last;#--нужное число нашел, выхожу из цикла
      }


}


$otz_klein =~ s!(.{$skolko_nuschno_simvolov}).*!$1...!;#--читаю символы и после нужного обрезаю, ставя троеточие



$kakoj_po_stschetu_teg = "1";#--ставлю по умолчанию какой по счету тег в массиве
$kakoj_po_stschetu_teg_v_perebore = "0";#--счетчик для подсчета строк массива


$otz_klein =~ s/</&vstavka_tegov($1)/ge;#--беру эмулятор и отсыдаю его в подпрограмму vstavka_tegov (> уберу потом, т.к. на <> может приходиться разрыв, после которого ставил троеточие. В этом случае обрезано будет на 1 символ меньше, но это не кретично.


      sub vstavka_tegov
      {

      foreach $perebor_tegov(@massiv_tegov)
         {
            chomp($perebor_tegov);

            ++$kakoj_po_stschetu_teg_v_perebore;

            if ($kakoj_po_stschetu_teg_v_perebore == "$kakoj_po_stschetu_teg")
               {
                  $teg_vosvrat="<$perebor_tegov>";
                  ++$kakoj_po_stschetu_teg;
                  last;
               }
         }

      $kakoj_po_stschetu_teg_v_perebore = 0;

            return $teg_vosvrat;
      }

$otz_klein =~ s/>>/>/g;

print "<hr>";
print "$otz_klein";
спустя 7 часов [обр] Евгений Седов aka KPbIC(0/187)[досье]
Agar -Agar[досье] Я имел в виду, что в файле с кодом Perl не должно быть HTML-разметки. Используйте шаблонизатор, в котором и так уже есть все, что вам нужно.
спустя 25 минут [обр] Прокаев2(0/35)[досье]
ужас
http://ru.wikipedia.org/wiki/%......%D0%BC%D1%8F%D1%82%D1%8C%D1%8E не так страшен . а код будет меньше и понятнее
Powered by POEM™ Engine Copyright © 2002-2005