0

約 100 個のファイルがあり、それらのそれぞれを調べて、間にあるすべてのデータを削除し、これらのタグも削除する必要が<style>あります。</style>

例えば

<html>
<head> <title> Example </title> </head>
<style>
p{color: red;
background-color: #FFFF;
}
div {......
...
}
</style>
<body>
<p> hi I'm a paragraph. </p>
</body>
</html>

なるべき

<html>
<head> <title> Example </title> </head>
<body>
<p> hi I'm a paragraph. </p>
</body>
</html>

また、一部のファイルでは、スタイル パターンは次のようになります。

<style type="text/css"> blah </style>

また

<link rel="stylesheet" type="text/css" href="$url_path/gridsorting.css">

3 つのパターンをすべて削除する必要があります。Perlでこれを行うにはどうすればよいですか?

4

6 に答える 6

6
use strict;
use warnings;

use XML::LibXML qw( );

my $qfn = 'a.html';

my $doc  = XML::LibXML->load_html( location => $qfn );
my $root = $doc->documentElement();

for my $style_node ($root->findnodes('//style')) {
   $style_node->parentNode()->removeChild($style_node);
}

{
   open(my $fh, '>', $qfn)
      or die;
   print($fh $doc->toStringHTML());
}

以下を正しく処理します。

  • タグ内に属性またはスペースを含むスタイル要素、
  • 複数行にわたるスタイル要素、
  • 複数行にわたるスタイルタグ、
  • スタイル要素の一部とその他のものを含む行、
  • 複数のスタイル要素を持つドキュメント、
  • 属性値のスタイルタグのように見えるもの、
  • CDATA ブロックのスタイル タグのようなもの、および
  • コメントのスタイルタグのように見えるもの。

この更新の時点で、他のソリューションはこれらのうち 2 つまたは 3 つしか処理しません。

于 2012-10-03T06:03:31.847 に答える
4

池上氏の言うとおり、このタスクを実行するには、少なくとも HTML/XML パーサーを使用する必要があります。Mojo::DOM個人的にはパーサーを使うのが好きです。これは HTML への Document-Object Model インターフェースであり、CSS3 セレクターをサポートしているため、必要なときに非常に柔軟になります。ただし、これは非常に簡単です。

#!/usr/bin/env perl

use strict;
use warnings;

use Mojo::DOM;

my $content = <<'END';
<html>
<head> <title> Example </title> </head>
<style>
p{color: red;
background-color: #FFFF;
}
div {......
...
}
</style>
<body>
<p> hi I'm a paragraph. </p>
</body>
</html>
END

my $dom = Mojo::DOM->new( $content );
$dom->find('style')->pluck('remove');

print $dom;

このpluckメソッドは少しややこしいですが、結果として得られる各オブジェクトに対してメソッドを実行するための簡単な方法です。類似の行は次のようになります。

$dom->find('style')->each(sub{ $_->remove });

これはもう少し分かりやすいですが、あまりかわいくありません。


基本的なフォーム以外にも対処する必要があるという編集を読んだ後、これが正規表現をばかげた比率に成長させるのではなく、HTML を変更するためにパーサーを使用する理由であることをさらに強調する必要があります。

ここで、$content変数にもこれらの行が含まれていたとしましょう

<link rel="stylesheet" type="text/css" href="$url_path/gridsorting.css">
<link rel="icon" href="somefile.jpg">

2番目ではなく最初のものを削除したい場所。これは、2 つの方法のいずれかで行うことができます。

$dom->find('link')->each( sub{ $_->remove if $_->{rel} eq 'stylesheet' } );

このメカニズムは、オブジェクト メソッド (および Mojo::DOM が属性をハッシュ キーとして公開する) を使用しlinkて、 rel=stylesheet. ただし、これらの要素にのみ CSS3 セレクターを使用することはできますがfind、Mojo::DOM には CSS3 セレクターが完全にサポートされているため、これを行うことができます。

$dom->find('link[rel=stylesheet]')->pluck('remove'); 

CSS3 セレクター ステートメントをカンマで結合して、いずれかのセレクターに一致するすべてのタグを検索できるため、単純に次の行を含めることができます。

$dom->find('style, link[rel=stylesheet]')->pluck('remove');

攻撃的なスタイルシートをすべて一挙に削除します!

于 2012-10-03T21:18:11.160 に答える
2

もう1つの可能な解決策は、を使用することHTML::TreeBuilderです。

#!/usr/bin/perl

use strict;
use warnings;
use HTML::TreeBuilder 5; # Ensure weak references in use

foreach my $file_name (@ARGV) {
  my $tree = HTML::TreeBuilder->new; # empty tree
  $tree->parse_file($file_name);
  # print "Hey, here's a dump of the parse tree of $file_name:\n";
  # $tree->dump; # a method we inherit from HTML::Element
  foreach my $e ($tree->look_down(_tag => "style")) {
      $e->delete();
  }
  foreach my $e ($tree->look_down(_tag => "link", rel => "stylesheet")) {
      $e->delete();
  }
  print "And here it is, bizarrely rerendered as HTML:\n",
    $tree->as_HTML, "\n";

  # Now that we're done with it, we must destroy it.
  $tree = $tree->delete; # Not required with weak references
}
于 2012-10-04T04:41:19.513 に答える
1

を使用した片道sed

sed '/<style>/,/<\/style>/d' file.txt

結果:

<html>
<head> <title> Example </title> </head>
<body>
<p> hi I'm a paragraph. </p>
</body>
</html>
于 2012-10-03T06:07:12.920 に答える
0

次の方法を試してください。

#! /usr/bin/perl -w
use strict;
my $line = << 'END';
<html>
<head> <title> Example </title> </head>
<style>
p{color: red;
background-color: #FFFF;
}
div {......
...
}
</style>
<body>
<p> hi I'm a paragraph. </p>
</body>
</html>
END

$line =~ s{<style[^>]*.*?</style>.}{}gs;
print $line;
于 2012-10-06T01:34:37.367 に答える
0
perl -lne 'print unless(/<style>/.../<\/style>/)' your_file

以下でテスト:

> cat temp
<html>
<head> <title> Example </title> </head>
<style>
p{color: red;
background-color: #FFFF;
}
div {......
...
}
</style>
<body>
<p> hi I'm a paragraph. </p>
</body>
</html>


> perl -lne 'print unless(/<style>/.../<\/style>/)' temp
<html>
<head> <title> Example </title> </head>
<body>
<p> hi I'm a paragraph. </p>
</body>
</html>
> 

インプレースで実行する場合は、次のようにします。

perl -i -lne 'print unless(/<style>/.../<\/style>/)' your_file
于 2012-10-03T09:53:35.723 に答える