Perl正規表現を使用して、HTML属性内の複数の単語を、それぞれが代替単語にハッシュ化して置き換えるにはどうすればよいですか?
-
07-07-2019 - |
質問
HTML難読化ツールを書いています。ユーザーフレンドリ名(IDとクラス)を難読化名(a、b、cなど)に関連付けるハッシュがあります。私は次のようなものを置き換えることを達成するための正規表現を思い付くのに苦労しています
<div class="left tall">
with
<div class="a b">
タグが1つのクラスしか受け入れられない場合、正規表現は次のようになります
s/(class|id)="(.*?)"/$1="$hash{$2}"/
引用符内の複数のクラス名を考慮して、これをどのように修正すればよいですか?できれば、ソリューションはPerl互換である必要があります。
解決
これを行うと思います:
s/
(class|id)="([^"]+)"
/
$1 . '="' . (
join ' ', map { $hash{これを行うと思います:
<*>} } split m!\s+!, $2
) . '"'
/ex;
他のヒント
最初に正規表現を使用するべきではありません。 1つの正規表現でやりすぎています( XMLとHTMLを正規表現で解析するのが難しい理由の例を示してください。理由)。必要なのはHTMLパーサーです。さまざまなパーサーを使用した例については、お気に入りのパーサーでHTMLを解析する例を提供できますかを参照してください。
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{最初に正規表現を使用するべきではありません。 1つの正規表現でやりすぎています( XMLとHTMLを正規表現で解析するのが難しい理由の例を示してください。理由)。必要なのはHTMLパーサーです。さまざまなパーサーを使用した例については、お気に入りのパーサーでHTMLを解析する例を提供できますかを参照してください。
HTML :: Parser
をご覧ください。 。以下に、おそらく不完全な実装を示します。
<*>} || 最初に正規表現を使用するべきではありません。 1つの正規表現でやりすぎています( XMLとHTMLを正規表現で解析するのが難しい理由の例を示してください。理由)。必要なのはHTMLパーサーです。さまざまなパーサーを使用した例については、お気に入りのパーサーでHTMLを解析する例を提供できますかを参照してください。
HTML :: Parser
をご覧ください。 。以下に、おそらく不完全な実装を示します。
<*> } @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>