1

我有一个 HTML 文件,其中包含一个 HTML 表格,其中包含指向科学论文和作者的链接以及他们的出版年份。html 从最旧到最新排序。我需要通过解析文件并获取一个包含从最新到最旧排序的源代码的新文件来使用表格。

这是一个小的 perl 脚本,应该可以完成这项工作,但它会产生半排序的结果

local $/=undef;
open(FILE, "pubTable.html")  or die "Couldn't open file: $!";
binmode FILE;
my $html = <FILE>; 
open (OUTFILE, ">>sorted.html") || die "Can't oupen output file.\n";
map{print OUTFILE "<tr>$_->[0]</tr>"} 
sort{$b->[1] <=> $a->[1]} 
map{[$_, m|, +(\d{4}).*</a>|]}
$html =~ m|<tr>(.*?)</tr>|gs;
close (FILE);  
close (OUTFILE);

这是我的输入文件: 链接

以及我得到的输出: 链接

从输出中您可以看到订单进展顺利,但是我在 1992 年之后得到了 1993 年,而不是在列表的开头。

4

3 回答 3

2

map由于 html 中的以下行,正则表达式存在问题。

<a href="http://www.icp.uni-stuttgart.de/~hilfer/publikationen/pdfo/">,{UCLA}-Report 982051,Los Angeles,,1989,</a></td>   </tr>

<a href="http://www.icp.uni-stuttgart.de/~hilfer/publikationen/pdfo/">Phys.Rev.Lett., <b> 60</b>, 1514, 1988</a></td>   </tr>
<a href="http://www.icp.uni-stuttgart.de/~hilfer/publikationen/pdfo/">Phys. Rev. B, <b> 45</b>, 7115, 1992</a></td>   </tr>
<a href="http://www.icp.uni-stuttgart.de/~hilfer/publikationen/pdfo/">J.Chem.Phys., <b> 96</b>, 2269, 1992</a></td>   </tr>

在 1989 行中,年份在末尾包含一个逗号,并且前面没有空格。正因为如此,脚本抛出了很多警告,并且总是把那行放在底部。

其他三行有一个四位数的数字(\d{4}),后面有一些东西.*(年份)。所以排序使用其他数字(7115、2269、1514)进行排序,这些数字与年份混淆。

您需要相应地调整正则表达式以解决这些问题。

前:

map{[$_, m|, +(\d{4}).*</a>|]}

后:

map{[$_, m|, *(\d{4}),?</a>|]}
于 2012-05-02T08:48:49.347 回答
1

还有一个带有 XML::Twig 的解决方案,它也可以用来处理 HTML。它相当健壮:它不会处理文件中的其他表格,它会容纳像 UCLA 报告中一年中的错别字......

#!/usr/bin/perl 

use strict;
use warnings;

use XML::Twig;

my $IN  = 'sort_input.html';
my $OUT = 'sort_output.html';

my $t= XML::Twig->new( twig_handlers => { 'table[@class="pubtable"]' => \&sort_table,
                                        },
                       pretty_print => 'indented',
                     )
       ->parsefile_html( $IN)
       ->print_to_file( $OUT);

sub sort_table
  { my( $t, $table)= @_;
   $table->sort_children( sub { if($_[0]->last_child( 'td')->text=~ m{(\d+)\D*$}s) { $1; } },
                          type => 'numeric', order => 'reverse'
                        );
  }
于 2012-05-02T11:47:53.723 回答
0

具有强大的 HTML 解析/操作库的解决方案:

use strictures;
use autodie qw(:all);
use Web::Query qw();
my $w = Web::Query->new_from_file('pubTable.html');
$w->find('table')->html(
    join q(),
    map { $_->[0]->html }
    sort { $a->[1] <=> $b->[1] }
    @{
        $w->find('tr')->map(sub {
            my (undef, $row) = @_;
            my ($year) = $row->find('.pubname')->text =~ /(\d\d\d\d) ,? \s* \z/msx;
            return [$row => $year];
        })
    }
);

open my $out, '>:encoding(UTF-8)', 'sorted.html';
print {$out} $w->html;
close $out;
于 2012-05-02T08:53:21.947 回答