【问题标题】:Using Perl, how can I remove the contents of a specific tag in an HTML document?使用 Perl,如何删除 HTML 文档中特定标签的内容?
【发布时间】:2012-09-22 09:44:41
【问题描述】:

我是 Perl 的新手。我必须在多行中查找和替换。

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

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

我的标签是,

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

现在替换为

<picture></picture> 

【问题讨论】:

  • 澄清一下,您想删除&lt;picture&gt; 标签内的所有标签,以及该标签上的任何属性?
  • 是的,我已经删除了“”中所有标签的所有属性和内部。

标签: perl html-parsing


【解决方案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;

【讨论】:

    【解决方案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;
        }
    }
    

    【讨论】:

      【解决方案3】:

      根据我认为您想要做的事情,以下是您需要更改的内容。您的表达式匹配任何&lt;picture&gt; 标记直到第一个&lt;/picture&gt; 标记,无论它是否真的关闭了您匹配的第一个标记。

      假设嵌套&lt;picture&gt;标签是非法的,你需要做的就是在替换的替换部分添加&lt;picture&gt;&lt;/picture&gt;,例如:

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

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

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

      这还不完美!例如,这个:

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

      将被替换为:

      &lt;picture&gt;&lt;/picture&gt;&lt;/picture&gt;

      但现在你已经到了一个正则表达式不够用的地步,你可能需要一个 XML 解析器。

      【讨论】:

      • "$content =~ s/]*>(.*?)//gis;"不会在我的文件中替换这些代码。
      • 您是逐行加载输入还是将整个内容加载到单个缓冲区中?您需要执行后者来进行多行搜索。通常的while (&lt;&gt;) { stuff } 将不起作用。
      • open(FOUT,"&gt;$filename") || die("Cannot Open File"); foreach my $line (@fcont) { $line =~ s/&lt;picture[^&gt;]*&gt;(.*?)&lt;\/picture&gt;/&lt;picture&gt;&lt;\/picture&gt;/gis; print FOUT $line; } close FOUT; 这些是我的代码。
      • 我认为$line 放弃了它。 ;-)
      • 这些是我的代码。 open(FILE, "$filename") or die("Cannot open the html files for reading\n"); my(@fcont) = &lt;FILE&gt;; close FILE; open(FOUT,"&gt;$filename") || die("Cannot Open File"); foreach my $line (@fcont) { $line =~ s/&lt;picture[^&gt;]*&gt;(.*?)&lt;\/picture&gt;/&lt;picture&gt;&lt;\/picture&gt;/gis; print FOUT $line; } close FOUT; 不会替换我的文件。任何人都可以帮助我。
      猜你喜欢
      • 2021-10-09
      • 1970-01-01
      • 2018-12-06
      • 1970-01-01
      • 1970-01-01
      • 2021-02-15
      • 1970-01-01
      • 2012-09-24
      • 1970-01-01
      相关资源
      最近更新 更多