使用Perl,如何删除HTML文档中特定标记的内容?

时间:2012-10-01 14:16:12

标签: perl html-parsing

我是Perl的新手。我必须找到并替换多行。

$content =~ s/<picture[^>]*>(.*?)<\/picture>//gis;

我尝试了这些代码。所有标签都在我的文件中替换。我有什么错误帮助我?

我的标签是,

<picture width='960' height='705' baseline='360'>
    <pict-header>
    </pict-header>
</picture>

现在由

取代
<picture></picture> 

3 个答案:

答案 0 :(得分:3)

根据我的想法,你需要改变。您的表达式会匹配任何<picture>代码,直至第一个</picture>代码,无论它是否实际关闭了您匹配的第一个代码。

假设嵌套<picture>标签是非法的,您需要做的就是在替换的替换部分添加<picture></picture>,例如:

$content =~ s/<picture[^>]*>(.*?)<\/picture>/<picture><\/picture>/gis;

提示:在处理包含斜杠的表达式时,请执行以下操作,这样就不需要转义斜杠了:

$content =~ s@<picture[^>]*>(.*?)</picture>@<picture></picture>@gis;

这仍然不完美!例如,这个:

<picture stuff="adfgerth"><picture stuff="235wefw45"><somejunk /></picture></picture>

将替换为:

<picture></picture></picture>

但是现在你已经达到了正则表达式还不够的程度,你可能想要一个XML解析器。

答案 1 :(得分:2)

使用HTML解析器解析HTML可以省去很多麻烦:

#!/usr/bin/env perl

use strict; use warnings;
use HTML::TokeParser::Simple;

die "Need filename\n" unless @ARGV == 1;
my ($filename) = @ARGV;

my $parser = HTML::TokeParser::Simple->new(file => $filename);

while (my $token = $parser->get_token) {
    if ($token->is_start_tag('picture')) {
        $parser->get_tag('/picture');
        print "<picture></picture>";
    }
    else {
        print $token->as_is;
    }
}

答案 2 :(得分:1)

Sinan的答案有效,但更好的解决方案可能是使用DOM解析器,例如Mojo::DOM(它是Mojolicious框架的一部分)。然后你可以做一些非常简单的操作,比如

#!/usr/bin/env perl

use strict;
use warnings;

use Mojo::DOM;

my $content = <<'END';
<picture width='960' height='705' baseline='360'>
    <pict-header>
    </pict-header>
</picture>
END

my $dom = Mojo::DOM->new($content);

$dom->at('picture')->replace('<picture></picture>')->root;

print $dom;