下面的代碼使用HTML::TreeBuilder模塊,這是一個用於解析HTML適當的工具。正則表達式不是。
#! /usr/bin/perl
use warnings;
use strict;
use HTML::TreeBuilder;
測試用例從你的問題:
my @cases = (
'<font color="#008080"><span style="background: #ffffff"></span></font>',
'<font color="#008080"> s</font>',
'<font></font>',
);
我們將使用is_empty
的謂詞的HTML::Element的look_down
方法找到<font>
元素,沒有有趣的內容。
sub is_empty {
my($font) = @_;
my $is_interesting = sub {
for ($_[0]->content_list) {
return 1 if !ref($_) && /\S/;
}
};
!$font->look_down($is_interesting);
}
最後主循環。對於每個片段,我們創建一個新的HTML::TreeBuilder
實例,刪除空的<font>
元素,並修剪剩下的第一層文本內容。
foreach my $html (@cases) {
my $tree = HTML::TreeBuilder->new_from_content($html);
$_->detach for $tree->guts->look_down(_tag => "font", \&is_empty);
my $result = "";
if ($tree->guts) {
foreach my $font ($tree->guts->look_down(_tag => "font")) {
$font->attr($_,undef) for $font->all_external_attr_names;
foreach my $text ($font->content_refs_list) {
next if ref $$text;
$$text =~ s/^\s+//;
$$text =~ s/\s+$//;
}
}
($result = $tree->guts->as_HTML) =~ s/\s+$//;
}
print "$result\n";
}
輸出:
<font>s</font>
製作兩遍是馬虎。該代碼可以改進:
#! /usr/bin/perl
use warnings;
use strict;
use HTML::TreeBuilder;
my @cases = (
'<font color="#008080"><span style="background: #ffffff"></span></font>',
'<font color="#008080"> s</font>',
'<font></font>',
);
foreach my $fragment (@cases) {
my $tree = HTML::TreeBuilder->new_from_content($fragment);
foreach my $font ($tree->guts->look_down(_tag => "font")) {
$font->detach, next
unless $font->look_down(sub { grep !ref && /\S/ => $_[0]->content_list });
$font->attr($_,undef) for $font->all_external_attr_names;
foreach my $text ($font->content_refs_list) {
next if ref $$text;
$$text =~ s/^\s+//;
$$text =~ s/\s+$//;
}
}
(my $cleaned = $tree->guts ? $tree->guts->as_HTML : "") =~ s/\s+$//;
print $cleaned, "\n";
}
使用正則表達式解析HTML的任何理由?您可能會使用Pearl的體面HTML解析器。來自Jamie Zawinski的引用:「有些人在遇到問題時想'我知道,我會用正則表達式'。現在他們有兩個問題。「 – 2010-09-18 11:26:21
[朋友不讓朋友用正則表達式解析HTML。](http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454) – Ether 2010-09-18 17:20:52
嗯,它實際上不是html代碼,它是我想清理的wiki代碼。 – cristi 2010-09-19 18:26:56