Рег выражаение для вырезания даных из кривой таблицы

  • Автор темы CrazyHacKeRs
  • Дата начала

CrazyHacKeRs

Guest
Рег выражаение для вырезания даных из кривой таблицы

Помогите составить регекс для вырезания информации из таблицы:
Проблемы в том, что теги не закрытые...

PHP:
<table class=t1 cellspacing=1 cellpadding=2>

<tr><td>field:<td >value 
<tr><td class=cell1>field2<td >value2
Нужно получить field : key
 

CrazyHacKeRs

Guest
Посмотрел, но не во всем пока разобрался ....

Каков план моих моих действий должен быть?

Задача: есть Html с нужной мне информацией (табличная структура: ключ, значение каждый в своем TD, те в свою очередь в TR'ах).

Таблиц может быть несколько (элементы дизайна), такаим образом мне сперва нужно вырезать как-то мою таблицу, а потом уже внутри ее выбирать параметры...

Что я должен делать при помощи этого парсера? Что с чем сравнивать, проверять....
 

Bloody

Guest
Я писал для таких вещей скрипты на перле... мне тоже очень много приходилось такой херней заниматься... работа здесь разделяется на два шага:

1) Ищешь, какая таблица твоя (т.е., выражение, или какие-то тэги, которые встречаются перед нужной тебе таблицей в каждом ХТМЛ файле, или все что угодно, дабы вычислить местоположение нужной таблицы), и все что ДО - просто игнорируешь.

2) Собственно, сама таблица: парсишь что-то типа:
$line =~ s/<td>(.*?)<td>(.*)$/$1.": ".$2/gie;
это конечно если каждая строка таблицы находится на новой строчке ХТМЛ-файла...

3) После закрывающего тэга </TABLE> - все остальное игнорируешь.

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

CrazyHacKeRs

Guest
А можешь скинуть скриптик, поробую адаптировать под себя?
 

Bloody

Guest
Ну, лови. Usage: parser.pl перечисление имен файлов.
Выходные файлы в нужном тебе формате, с таким же именем, но с расширением .out. Под твои нужды я его переделал, кроме переменной $headend_marker.

#!/usr/local/bin/perl

foreach(@ARGV){

open F, $_;

$fn=$_;
$fn=~s/(.+)\..*/$1.".out"/gie;

open R, ">".$fn;

$headend_marker="<html>";

$headskipped=0;
$allowparsing=0;
while($line=<F>)
{
if($allowparsing)
{
if($line=~/<\S*\/\S*table/i)
{
$allowparsing=0;
$headpassed=0;
last;
}
$line=~s/<\S*td.*?>(.*?)<\S*td.*?>(.*?)/$1.": ".$2/gie;
chomp $line;
print R $line."\n";
}
if($headskipped && !$allowparsing)
{
if($line=~/<\S*table/i)
{
$allowparsing=1;
}
}
if($line=~/$headend_marker/i)
{
$headskipped=1;
}
}
close F;
close R;
}
 

CrazyHacKeRs

Guest
Мешает, голова :D

Спасибки, буду разбираться....
 

CrazyHacKeRs

Guest
Ты знаешь, так получилось что информация между TD имеет перевод каретки и строки, в результате чего лишь часть информации обрабатывается....

Как бы убрать все переводы между
<TD>строка1
строка 2
строка 3
<TR>

сделав:
<TD> строка 1 строка 2 строка 3
<TR>


????
 

Bloody

Guest
Вот измененный код (опять таки: headend_marker вставишь свой):

Код:
#!/usr/local/bin/perl

foreach(@ARGV){

open F, $_;

$fn=$_;
$fn=~s/(.+)\..*/$1.".out"/gie;

open R, ">".$fn;

$headend_marker="<html>";

$headskipped=0;
$allowparsing=0;
while($line=<F>)
{
    if($allowparsing)
    {
        chomp $line;
        $line .= " ";
        if($line=~/<\s*\/\s*table/i)
        {
            $allowparsing=0;
            $headpassed=0;
            last;
        }
        $line=~s/<\s*tr[^>]*>/"\n"/gie;
        $line=~s/\n\s+/"\n"/gie;
        $line=~s/<\s*?td.*?>/: /gi;
        $line=~s/\n: /"\n"/gie;
        $line=~s/^: /""/gie;
        print R $line;
    }
    if($headskipped && !$allowparsing)
    {
        if($line=~/<\s*table/i)
        {
            $allowparsing=1;
        }
    }
    if($line=~/$headend_marker/i)
    {
        $headskipped=1;
    }
}
close F;
close R;
}
Пробуй :)
 

Yukko

Новичок
2 All, кто сюда парит перл... Я вот смотрю на Вас уже дня три и больно становится... :(
Ребята пните меня больно, но это форум по РНР и решение предложенной проблемы простое:
preg_match_all("/<td(.*?)>(.*?)(?=[<\n\s])/s",$line,$matches);
print_r($matches);
Объясняю приведенный рег
<td(.*?)> - матчит открытый тег td
(?=[<\n\s]) - позитивная ретроспективная проверка!
ее суть заключается в том, что она совпадает не с символом, а с местом в тексте... данная ретроспективная проверка совпадет перед символом новой строки, перед пробелом и перед открывающеяся < нового тега,
само значение после тега <td> запоминается за счет выражения
(.*?)
Разберем выражение .*?
точка со звездочкой будут матчить все после первого открытого тега td, нам это не надо... с жадностью в таком случае надо бороться... боремся:
Ставим ? , который укажет, что надо матчить все, но если надо что-то отдать для других частей рега, которые идут после (.*?), то ОТДАВАТЬ ОБЯЗАТЕЛЬНО, тот же алгоритм и в <td(.*?)> матчить все от
<td до > если не надо матчить то, что внутри тега <td class=bla>, то ставятся несохраняющие круглые группирующие скобки (?:.*?)
Вот вроде и все... данному регу пофигу, закрываются у тебя теги <td> или нет!
 
Сверху