Html Perl中模式所需的单行正则表达式

Html Perl中模式所需的单行正则表达式,html,regex,perl,match,Html,Regex,Perl,Match,我需要使用perl读取许多包含类似结构的HTML文件 结构包括 STRRRR…E S=表格开始前的html标题 T=html文件中唯一的表开始结构(我可以识别) R=一组html元素(那些是tr,我也能识别) E=所有剩余-单端R 我想使用单行“m”perlop提取数组中的所有R。 我在找这样的东西: @all_Rs=$htmlfile=~m{ST(R)*E}gs 但它从未成功过 到目前为止,我一直在做一个迂回的方法,比如使用删除不需要的文本、for循环等。 我要从此页中提取所有行: 有很多

我需要使用perl读取许多包含类似结构的HTML文件

结构包括 STRRRR…E

  • S=表格开始前的html标题
  • T=html文件中唯一的表开始结构(我可以识别)
  • R=一组html元素(那些是tr,我也能识别)
  • E=所有剩余-单端R
我想使用单行“m”perlop提取数组中的所有R。

我在找这样的东西:

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

但它从未成功过

到目前为止,我一直在做一个迂回的方法,比如使用删除不需要的文本、for循环等。 我要从此页中提取所有行:
有很多这样的页面。

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;
my$tree=HTML::TreeBuilder::XPath->new_from_content(findnodes('//tr');

继承自。

daxim使用真正的解析器是正确的。我个人的选择是

这会让我从那页上看到每一行

再多做一点工作,我们就可以有一个很好的数据结构来保存每个单元格中的文本

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;

如果要处理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";
   }
}

这是今天第三次或第四次有人想用regexp做一些事情,但坚持用一个,singel,Glory regex做。这是一项运动还是什么?我放弃了。只是这么多:这是合理的,因为坚持在一个大表达式中有一个复杂的功能(而不是函数、模块等)首先不要用正则表达式解析HTML:你有S、t、R和E正则表达式吗?如果有,并且它们单独工作,你可以像你概述的那样将它们组合在一起。@Ingo我喜欢你的短语“这是运动吗?”也许事实上是这样。@user656848,这应该是一个很好的线索,说明为什么正则表达式也不能满足您的需要。坏页面往往会变得更糟,或者随着时间的推移得到修复,无论哪种方式,您的正则表达式都会崩溃。不,不,我正在处理语法不正确的html文件,并且许多打开-关闭标记都是错误的正在处理。这就是我不使用DOM遍历树的原因。我要提取的所有行:。请注意,此页面存在大量html错误,是我一生中见过的最糟糕的页面。我在哪里可以下载XML模块和文档?我回答中的链接将指向一个包含文档的CPAN页面,以及您可以下载的文件手动安装。如果您在Linux或类似系统上,您的发行版可能有一个可以安装的软件包,否则如果您具有root访问权限,则可以使用
cpan
命令,例如
cpan XML::LibXML
。如果您在Windows上使用ActivePerl,则它附带一个工具
ppm
,该工具应该能够安装XML::LibXML。
#!/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";
   }
}