Однострочное регулярное выражение, необходимое для шаблона в Perl - PullRequest
0 голосов
/ 25 марта 2011

Мне нужно прочитать много HTML-файлов, содержащих похожую структуру, используя perl.

Структура состоит из STRRRR ... E

  • S = заголовок html непосредственно перед началом таблицы
  • T = уникальная начальная структура таблицы в html-файле (я могу ее идентифицировать)
  • R = Группа html-элементов (это tr, я тоже могу их идентифицировать)
  • E = Все остальное - объединяет конец R

Я хочу извлечь все R в массив, используя однострочный "m" perlop.

Я ищу что-то вроде этого:

@ all_Rs = $ htmlfile = ~ m {ST (R) * E} gs;

Но это никогда не получалось.

До сих пор я обдумывал способ сделать это, например, удалить ненужный текст, цикл и т. Д. Я хочу извлечь все строки с этой страницы: http://www.trainenquiry.com/StaticContent/Railway_Amnities/Enquiry%20-%20North/STATIONS.aspx и таких страниц много.

Ответы [ 3 ]

5 голосов
/ 25 марта 2011

Regex - неправильный инструмент. Используйте анализатор HTML.

use HTML::TreeBuilder::XPath;
my $tree= HTML::TreeBuilder::XPath->new_from_content(<<'END_OF_HTML');
<html>
    <table>
        <tr>1
        <tr>2
        <tr>3
        <tr>4
        <tr>5
    </table>
</html>
END_OF_HTML

print $_->as_text for $tree->findnodes('//tr');

HTML :: TreeBuilder :: XPath наследуется от HTML :: TreeBuilder .

2 голосов
/ 26 марта 2011

Если вы хотите обработать таблицу HTML, рассмотрите возможность использования модуля, который знает, как обрабатывать таблицы HTML!

#!/usr/bin/perl
use warnings;
use strict;
use LWP::Simple;
use HTML::TableExtract;


my $html = get 'http://www.trainenquiry.com/StaticContent/Railway_Amnities/Enquiry%20-%20North/STATIONS.aspx';
$html =~ s/&nbsp;/ /g;

my $te = new HTML::TableExtract( depth => 1, count => 2 );
$te->parse($html);
foreach my $ts ($te->table_states) {
   foreach my $row ($ts->rows) {
      next if $row->[0] =~ /^\s*(Next|Station)/;
      next if $row->[4] =~ /^\s*(ARR\/DEP|RESERVATION)/;
      foreach my $cell (@$row) {
          $cell =~ s/^\s+//;
          $cell =~ s/\s+$//;
          print "$cell\n";
      }
      print "\n";
   }
}
2 голосов
/ 25 марта 2011

daxim прав в использовании настоящего парсера.Мой личный выбор: XML :: LibXML .

use XML::LibXML
my $parser = XML::LibXML->new();
$parser->recover(1);                 # don't fail on parsing errors
my $doc = do { 
    local $SIG{__WARN__} = sub {};   # silence warning about parsing errors
    $parser->parse_html_file('http://www.trainenquiry.com/StaticContent/Railway_Amnities/Enquiry%20-%20North/STATIONS.aspx');
};

print $_->toString() for $doc->findnodes('//tr[td[1][@class="td_background"]]');

. Здесь я получаю каждую строку станции с этой страницы.структура данных для хранения текста в каждой ячейке.

use Data::Dumper;
my @data = map {
    my $row = $_;
    [ map {
        $_->findvalue('normalize-space(text())');
    } $row->findnodes('td') ]
} $doc->findnodes('//tr[td[1][@class="td_background"]]');
print Dumper \@data;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...