2009-08-01 3 views
3

私はHTMLの難読化装置を書いています。わかりやすい名前(a、b、cなど)にユーザーフレンドリーな名前(IDとクラス)を関連付けるハッシュがあります。私はタグが唯一のクラスを受け入れることができれば、正規表現は、単にPerlの正規表現を使用して、HTML属性の複数の単語をそれぞれ代替単語に置き換えるにはどうすればよいですか?

s/(class|id)="(.*?)"/$1="$hash{$2}"/ 
ようなものになるだろう

<div class="a b"> 

<div class="left tall"> 

のようなものを置き換える達成するための正規表現を考え出すのトラブルを抱えています

引用符で囲まれた複数のクラス名について、これを修正するにはどうすればよいですか?好ましくは、解決策はPerl互換でなければならない。

+0

「left」と「tall」は、「a」と「b」と同じように難読化されていることがあります。 –

答えて

-1

は、私はこれを行うだろうと推測する:あなたが最初の場所で、このために正規表現を使用すべきではない

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

HTMLのテキストにclass = "foo"が含まれているときはどうしますか?単一の正規表現/置換は、再帰的に構造化されたデータとうまく組み合わされません。 –

6

。あなたは1つの正規表現であまりにも多くをやろうとしています(理由については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> 
関連する問題