我有一组 HTML 报告,每个报告都包含两个具有特定 ID 的 DIV 元素,我需要将其剥离并编译成一个整体摘要报告(同样是一个 HTML 文件)。
我最初的想法是,这是 Perl 脚本的理想工作,但是我们没有最新的内部 Perl 技能(我们是一家 .NET C# 商店)。
欢迎对推荐方法提出想法和建议......
我有一组 HTML 报告,每个报告都包含两个具有特定 ID 的 DIV 元素,我需要将其剥离并编译成一个整体摘要报告(同样是一个 HTML 文件)。
我最初的想法是,这是 Perl 脚本的理想工作,但是我们没有最新的内部 Perl 技能(我们是一家 .NET C# 商店)。
欢迎对推荐方法提出想法和建议......
使用合适的 HTML 解析器;Perl有HTML::Parser,我相信 C# 也有几个。
使用 Perl、HTML::TokeParser和HTML::Template会有所帮助。这是一个简单的例子:
#!/usr/bin/perl
use strict;
use warnings;
use HTML::TokeParser;
use HTML::Template;
use Data::Dumper;
my ($html_file) = @ARGV;
open my $html_handle, '<:utf8', $html_file
or die "Cannot open '$html_file': $!";
my $parser = HTML::TokeParser->new( $html_handle );
my @divs;
while ( my $tag = $parser->get_tag('div') ) {
my $attr = $tag->[1];
next unless ref $attr eq 'HASH';
next unless defined( my $id = $attr->{id} );
next unless $id eq 'div1' or $id eq 'div2';
my $div = $tag->[-1];
my $in_wanted = 1;
while ( $in_wanted ) {
my $token = $parser->get_token;
if ( $token->[0] eq 'T' ) {
$div .= $token->[1];
}
else {
$div .= $token->[-1];
}
my ($type, $name) = @$token[0, 1];
if ( $name eq 'div' ) {
$in_wanted += $type eq 'S' ? 1
: $type eq 'E' ? -1
: 0;
next;
}
if ( $type eq 'E' and $name eq 'html' ) {
warn "Warning: Reached the end of '$html_file'\n";
last;
}
}
push @divs, {DIV => $div};
}
print output( @divs );
sub output {
my $tmpl_html = <<EO_TMPL;
<html>
<body>
<TMPL_LOOP DIVS>
<TMPL_VAR DIV>
</TMPL_LOOP>
</body>
</html>
EO_TMPL
my $tmpl = HTML::Template->new(
scalarref => \$tmpl_html,
);
$tmpl->param( DIVS => \@_ );
return $tmpl->output;
}
如果您的 div 包含嵌套的 div ,那么简单的正则表达式可能还不够。这是因为结束 div 元素不包含 ID,因此正则表达式很难匹配结束标记。
如果你的 div 是:
<div id="findme">
<!-- No other divs here! -->
</div>
然后你可以使用正则表达式(只是要小心贪婪),这是一个更优雅的版本:
<div id="findme">(.*?)</div>
注意:我很确定正则表达式不会运行,已经有一段时间了!
我会考虑使用 HTML 解析器库来解析结构并获取 div 内部的字符偏移量,然后从缓冲区中获取该范围。使用 HTML 库将允许您解析并找到您想要的 div 结束的位置。
像本教程这样的东西可能会有用。这些解析器可能允许您准确地提取包含在标签中的数据,例如您的 div。
您还可以使用C# HTML 解析器,它们都做类似的工作,只需查看文档以确保它们不只是构建树,并允许您获取包含的 div 数据的字符偏移量(以便您可以提取它)或允许访问该数据。