Perl-删除表标记之间的字符串



我是Perl的新手,在某些情况下正在尝试从HTML文件中删除表。

下面是一个示例。如果字符串不包含字符串 xyz,我想删除表标签之间的字符串。但是代码不起作用,它不会删除第一个表。我应该如何修改代码以使其正常工作?谢谢!!

这是我的代码:

use strict;
use warnings;
use autodie;
my $data = <<TEXT;
<table>
(aaa)
</table>
<table>
xyz
</table>
TEXT
my @find=();
@find=$data =~ m/<TABLE[^>]*>(.*?)</TABLE>/imosg;
foreach (@find) {
if ($_!~ m/xyz/imosg){$data =~ s/$_//;}
}
print "$datan","*" x 40, "n" ;

尽管您可以使用正则表达式来快速和肮脏地操作 HTML,但您可能希望考虑使用 HTML 解析器作为一种不太容易出错的方法。 下面是一个示例:

#!/usr/bin/perl
use 5.012;
use strict;
use warnings;
use autodie;
use XML::LibXML;
my $html = <<'EOF';
<!DOCTYPE html>
<html>
<head>
<title>Test Document</title>
</head>
<body>
<table>
<thead>
<tr><th>Country</th><th>Population</th></tr>
</thead>
<tbody>
<tr><td>Lithuania</td><td>2,908,249</td></tr>
<tr><td>Bermuda</td><td>61,666</td></tr>
</tbody>
</table>
<table>
<thead>
<tr><th>Country</th><th>Population</th></tr>
</thead>
<tbody>
<tr><td>Botswana</td><td>2,250,260</td></tr>
<tr><td>Dominica</td><td>73,543</td></tr>
</tbody>
</table>
</body>
</html>
EOF
my $dom = XML::LibXML->load_html(
string  => $html,
recover => 1,
);
foreach my $table ($dom->findnodes('//table')) {
my $text_content = $table->to_literal;
if($text_content =~ /botswana/i) {
$table->parentNode->removeChild($table);
}
}
say $dom->toStringHTML();

再举一些例子。

use Web::Query::LibXML 'wq';
my $w = wq <<'HTML';
<html><body>
<table>
(aaa)
</table>
<table>
xyz
</table>
HTML
$w->find('table:not(:contains("xyz"))')->html('');
print $w->as_html;

@find包含字符串n(aaa)n(其中n是换行符(。当您调用$data =~ s/$_//时,您不匹配,因为$_中的括号字符是正则表达式元字符。$data =~ s/n(aaa)n//不匹配并替换字符串n(aaa)n;它匹配字符串naaan并将字符串aaa作为捕获组返回(例如,在特殊变量$1中(。

Perl 提供了几种机制来匹配正则表达式中的文字字符串。一种是将字符串包装在Q和(有时是可选的(E标签中:

$data =~ s/Q$_E//;           # match literal contents of $_

第二种方法是在应用正则表达式之前使用quotemeta函数。

my $q = quotemeta($_);
$data =~ s/$q//;
$data =~ s{(<table.*?>)(.*?)(</table>)}
{
my($one,$two,$three) = ($1,$2,$3);
$two =~ /xyz/
? "$one$two$three"
: "$one$three"
}esig;

。但是,如果您在<表>中有一个<表>,则这不起作用。如果是这样,请进行真正的HTML解析。

最新更新