• ベストアンサー

<div>タグの中の<img>タグのclass属性を削除したい

<div class="center"> .... <img ... class="right" ...> .... </div> とあるソースをperlを使って <div class="center"> ... <img ...> ... </div> というように img タグの class="right" を削除したいです。 <div class="center"> の中にあるimgタグのみ対象としたいのですが、 どうすればよいのでしょうか。 なお、<div class="center"> タグの中には複数の <img ... class="right" .. >タグがある場合もあります。

質問者が選んだベストアンサー

  • ベストアンサー
  • kumoz
  • ベストアンサー率64% (120/185)
回答No.4

実際のファイルを処理するには、いろいろと難しい問題があるように思います。次の簡単な コードは、</div> を忘れているとダメ、複数の </div> が同じ行にあるとダメというもの ですが、出発点ぐらいにはなると思います。 use strict; my ($range_end, $depth, $r) = ('</div>'); while (<DATA>) { if ($r = /<div class="center">/ .. m!$range_end!) { s/(<img [^>]*?) ?class="right"/$1/; $depth = 0 if $r == 1; if ($r > 1 and /<div /) { $range_end = 'dummy_string' unless $depth; $depth++; } if ($depth and m!</div>!) { $depth--; $range_end = '</div>' unless $depth; } } print; } __DATA__ <div class="center"> <img src="xxx.gif" class="right" alt=""> (削除) </div> <div class="other"> <img src="xxx.gif" class="right" alt=""> (そのまま) </div> <div class="center"> <img src="xxx.gif" class="right" alt=""> (削除) <div class="other"> <img src="xxx.gif" class="right" alt=""> (削除) </div> </div> <div class="other"> <img src="xxx.gif" class="right" alt=""> (そのまま) <div class="center"> <img src="xxx.gif" class="right" alt=""> (削除) </div> </div>

yocean1201
質問者

お礼

ありがとうございます。 実はhtmlファイルを丸ごと読み込んで、正規表現で変更するという処理をこの前にしています。 ですので、できれば1行ごとの処理でなく、html丸ごとに対して変換できるような正規表現が可能であれば教えていただきたいです。 それなら </div> が1行に複数あろうが単体であろうが問題ないですよね。

その他の回答 (3)

回答No.3

http://search.cpan.org/search?query=HTML+Parser&mode=all http://search.cpan.org/search?query=XML+Parser&mode=all http://search.cpan.org/search?query=SGML+Parser&mode=all HTML::Parserのような名前をしたモジュールを使うのが正攻法だと思います。 しかし、属性を削除するために使ったことがないので具体的な手順までは分かりません。 そのため、私は正規表現で何とかしようと思い立ち、計算によって以下のコードを導き出しました: ----- #!/usr/bin/perl use strict; use warnings; my $flag; while (<>) { $flag and s/(<img(?= ).*?) class="right"(.*?>)/$1$2/; $flag = 1 if /<div(?= ).*? class="center".*?>/; undef $flag if m|</div>|; print; } ----- $ ./delete.pl index.html index2.html のように、コマンドライン引数としてtext/htmlファイルを渡すと、ご質問の処理を行った後のHTML文書を標準出力に出力します。 私の環境でテストしたところ、All tests successfulでした。 しかし即興によるコードなので動く保証はありません。参考程度にお願いします。

yocean1201
質問者

お礼

HTML::TagParser を使ってみました。 getElementsByTagName( "div" ) で div タグの一覧を取得し、 attributes で属性と指定値が class="center" となるものを選別まではできますが、 そのノードの中身全部を取得するメソッドがないみたいです。 ノードの中のテキストを取得する innerText というメソッドはありますが、img タグは取得できません。 これが取得できれば、あとは img タグの class="right" を正規表現で削除するだけなんですけどね・・・。 いただいた方法なんですけど、No.4 と同じく1行ごとの処理ではなく、 $html にHTMLのソースがすべて入っているとしたときに どうしたらよいか教えていただけないでしょうか。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

や, 使ったことはないけど HTML の解析モジュールなんか探せばその辺に転がってるような気がする.

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

div のネストを考慮するかどうかによるんだけど, まじめにやるなら何らかのモジュールを使ってソースを解析する. 手を抜いていいなら正規表現 (じゃないけど) +α で何とかなる.

yocean1201
質問者

お礼

div のネストもあります。 何らかのモジュールって、どんなモジュールがあるのでしょうか?

関連するQ&A