如何使用Perl删除HTML文件中p元素的所有属性?

时间:2011-10-25 08:31:10

标签: html regex perl command-line

我想使用这个简单的Perl命令行删除HTML文件中<p>的所有属性:

$ perl -pe 's/<p[^>]*>/<p>/' input.html

然而,它不会替代,例如<p class="hello">跨越多行,例如

<p 
class="hello">

因此,我试图通过执行

来删除行尾
# command-1
$ perl -pe 's/\n/ /' input.html > input-tmp.html
# command-2
$ perl -pe 's/<p[^>]*>/<p>/g' input-tmp.html > input-final.html

问题:

  1. (Perl)正则表达式中是否有选项可以跨多行尝试匹配?
  2. 我可以将上面的两个命令( command-1 command-2 )组合成一个吗?基本上,第一个命令需要在第二个命令开始之前完成执行。

4 个答案:

答案 0 :(得分:3)

-p

的缩写
LINE: while (<>) {
   ...
} continue {
   print
      or die "-p destination: $!\n";
}

正如您所看到的,$_一次只包含一行,因此该模式不可能匹配跨越多行的内容。您可以使用-0777来欺骗Perl认为整个文件是一行。

perl -0777 -pe's/<p[^>]*>/<p>/g' input.html

命令行选项记录在perlrun

答案 1 :(得分:1)

如果编写一个简短的脚本,并将其放在自己的文件中,则可以使用简单的命令行轻松调用它。

改进以下脚本作为练习:

#!/usr/bin/perl

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

run(\@ARGV);

sub run {
    my ($argv, $opt) = @_;

    my $el = shift @$argv;

    for my $src (@$argv) {
        clean_attribs($src, $el, $opt);
    }
}

sub clean_attribs {
    my ($src, $el, $opt) = @_;
    my $el_pat = qr/^$el\z/;

    my $parser = HTML::TokeParser::Simple->new($src, %$opt);

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

答案 2 :(得分:0)

perl -pe 'undef $/; s/<p[^>]*>/<p>/g'

答案 3 :(得分:-3)

$ perl -pe 's/\n/ /; s/<p[^>]*>/<p>/gs;' input.html > input-final.html