2009-08-01 36 views
3

我正在編寫一個HTML混淆器,並且我有一個將混淆名稱(如a,b,c等)的用戶友好名稱(ids和類)相關聯的哈希。我無法想出一個正則表達式爲完成更換像如何使用Perl正則表達式在HTML屬性中替換多個單詞,每個單詞都被散列爲一個替代單詞?

<div class="left tall"> 

<div class="a b"> 

如果標籤只能接受一個類,正則表達式,簡直是像

s/(class|id)="(.*?)"/$1="$hash{$2}"/ 

我應該如何解決這個問題以解釋引號內的多個類名?該解決方案最好是Perl兼容的。

+0

有些人可能會說`left`和`tall`就像`a`和`b`一樣被模糊處理。 – 2009-08-01 22:43:45

回答

-1

我想我應該這樣做:

s/ 
    (class|id)="([^"]+)" 
/ 
    $1 . '="' . (
     join ' ', map { $hash{$_} } split m!\s+!, $2 
    ) . '"' 
/ex; 
+0

當HTML的文本包含class =「foo」時,你會做什麼?單個正則表達式/替換不能很好地與遞歸結構化數據混合使用。 – 2009-08-01 18:33:35

6

你不應該首先使用正則表達式這一點。你正試圖用一個正則表達式做太多事情(爲什麼要參考Can you provide some examples of why it is hard to parse XML and HTML with a regex?)。你需要的是一個HTML解析器。有關使用各種解析器的示例,請參閱Can you provide an example of parsing HTML with your favorite parser?

看看HTML::Parser。這裏有一個可能不完整的實現:

#!/usr/bin/perl 

use strict; 
use warnings; 

use HTML::Parser; 

{ 
    my %map = (
     foo => "f", 
     bar => "b", 
    ); 

    sub start { 
     my ($tag, $attr) = @_; 
     my $attr_string = ''; 
     for my $key (keys %$attr) { 
      if ($key eq 'class') { 
       my @classes = split " ", $attr->{$key}; 
       #FIXME: this should be using //, but 
       #it is only availble starting in 5.10 
       #so I am using || which will do the 
       #wrong thing if the class is 0, so 
       #don't use a class of 0 in %map , m'kay 
       $attr->{$key} = join " ", 
        map { $map{$_} || $_ } @classes; 
      } 
      $attr_string .= qq/ $key="$attr->{$key}"/; 
     } 

     print "<$tag$attr_string>"; 
    } 
} 

sub text { 
    print shift; 
} 

sub end { 
    my $tag = shift; 
    print "</$tag>"; 
} 

my $p = HTML::Parser->new(
    start_h => [ \&start, "tagname,attr" ], 
    text_h => [ \&text, "dtext" ], 
    end_h => [ \&end, "tagname" ], 
); 

$p->parse_file(\*DATA); 

__DATA__ 
<html> 
    <head> 
     <title>foo</title> 
    </head> 
    <body> 
     <span class="foo">Foo!</span> <span class="bar">Bar!</span> 
     <span class="foo bar">Foo Bar!</span> 
     This should not be touched: class="foo" 
    </body> 
</html> 
相關問題