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

Удалить из текста все кроме таблиц

Метки: [без меток]
2004-12-17 18:15:30 [обр] lavan(0/7)[досье]

Задача: удалить всё, кроме таблиц и их содержимого, т.е. все что в промежутках, до и после таблиц подлежит удалению.
Как выделить таблицу, я знаю:

$string =~ s/<table[^>]*>((?!<\/?table>).*)<\/table>/$1/sig;

Всегда сталкивался с обратной задачей, - найти требуеемый текст и заменить его/удалить. А тут требуется наоборот, - требуемый текст оставить, а всё остальное удалить. Может я туплю, но что то не могу найти очевидного решения.
Напрашивается следующее:

$string =~ s/.*(<table[^>]*>((?!<\/?table>).*)<\/table>).*/$1/sig;

но естественно не работает, - удаляет всё кроме посл. таблицы в тексте, минимальные квантификаторы не помогли :-(

спустя 17 минут [обр] Алексей В. Иванов(17/2861)[досье]
Если таблицы не вложенные, то должен работать такой простой вариант:
$string =~ s/^.*?<table/<table/si;
$string =~ s/<\/table>.*?<table/<\/table><table/sig;
$string =~ s/<\/table>.*?$/</table>/si;
спустя 29 минут [обр] lavan(0/7)[досье]

Алексей В. Иванов[досье], спаисбо за подсказку! вы только описались в посл. строчке -

$string =~ s/<\/table>.*?$/<\/table>/si;

Сорри, что забыл предупредить, но как это у нас водится, таблицы бывают вложенные.
Я хочу универсальное решение, чтобы проблем потом не было.
Мне нужно удалять всё, кроме таблиц, т.е. фактически оставлять только контент тегов <TD> и обрамляющих их таблиц со всеми причендалами.
Это мне нужно для визуального представления разметки(структуры) страницы в виде ячеек в редакторе сайта.

спустя 18 часов [обр] DJ G.E.D(0/101)[досье]
Для удаления вложенных таблиц придется вводить счетчик вложений, так что одними регулярками не обойтись. Кстати, стоит заранее подумать о валидности html-кода или об интерпретации страниц с пропущенными тегами.
спустя 3 минуты [обр] DJ G.E.D(0/101)[досье]
Не удаления, а выделения разумеется.
спустя 4 года [обр] lavan(0/7)[досье]

Решил задачу следующим способом. На помощь пришел use HTML::TreeBuilder;

  my $tree = HTML::TreeBuilder->new; # empty tree
  $tree->parse($HTML);

  $tree->eof();
  $tree->implicit_tags(1);
  $tree->elementify();

  extract_table($tree);

  $HTML = $tree->as_HTML('&"');
  $tree->delete();

и собственно моя функция:

#==========================================================
# Вытаскивает из HTML-кода все таблицы
#==========================================================
sub extract_table($) 
{
  my $tree = shift;

  foreach my $item_r ( $tree->content_refs_list )
  {
    
    if (not ref $$item_r) # Просто текст!
    {
      $$item_r = '';
      next;
    }

     # 1. Проверим таблица ли это?
     my $tag = $$item_r->tag();

     if (grep /^t(d|r|h|head|foot)$/, $tag) {} # этот тег связан с таблицей, оставляем
     else # тег не является таличным и внутри него нет ячеек, удаляем!
     {
       $$item_r->delete();
       next;
     }

     # 2. Это таблица, устанавливаем нужные атрибуты.
     my %attr = $$item_r->all_attr();
     if ($tag eq 'table')
     {
       map { $$item_r->attr($_, undef) } grep !/_(tag|parent|content|width|height)/, keys %attr;
     }
     elsif ($tag eq 'tr')
     {
       map { $$item_r->attr($_, undef) } grep !/_(tag|parent|content)/, keys %attr;
     }
     elsif ($tag eq 'td')
     {
       map { $$item_r->attr($_, undef) } grep !/(_tag|_parent|_content|width|height|colspan|rowspan)/, keys %attr;
     }

     &extract_table($$item_r); 
  }
  return;
}#extract_table
Powered by POEM™ Engine Copyright © 2002-2005