0

こんにちは、HTML::TreeBuilder/を使用HTML::Elementして、Microsoft Word などのプログラムによって生成された不適切な HTML をクリーンアップしています。

例の不適切な HTML のスニペットを考えると、 と の間のテキストを抽出する必要がありmosh="start"ますmosh="stop"。これは、コード内の別の場所で設定された任意の属性であることに注意してください。

また、これは単なる例であることに注意してください。唯一の保証は、divmosh の開始場所と停止場所です。これらはテーブルまたは<p><b>.

以下のコードはこれを実現しますが、各子にも子があるため、各行は複数回抽出されます。

$MoshTextする必要があります

Good Text can be pattern matched Wanted Text More Wanted TextYet More Wanted Text

しかし、テーブルの後

$MoshText

Good Text can be pattern matched Good Text can be pattern matched Good Text can be pattern matched Good Text can be pattern matched

次に、2 つの文字列に分割$MoshTextm/matched/、元のテキストが含まれていたオブジェクトをすべて削除する必要があります。

これを実現するために以下のコードを変更するにはどうすればよいですか?

#!/usr/bin/perl
use HTML::TreeBuilder;
use HTML::Element;

my $body =qq(
<body>
  <div mosh="start">Div where mosh set to start</div
  <div>
<table>
  <tr>
    <td></td><td</td>
    <th>Good Text can be pattern matched</th>
    <td></td><td</td>
  </tr> 
</table
</div>
<p>

   <p>
      <b>Wanted Text</b>
   <br>
      <p><b>More Wanted Text</b></p>
   <div>
      <p><b>Yet More Wanted Text</b></p>
   </div>
  </p>
<div mosh="stop">Div where mosh set to stop bellow here is not needed</div>
);

my ($MoshText, $Flag);

my @kids = $body->content_list();
while (@kids) {
    my $child = shift @kids;
    if (ref $child) {
        my $Mosh = child->attr("mosh");
        if ($Mosh eq "start") {
            $Flag = 1;
        }
        if ($Mosh eq "stop") {
            $Flag = 0;
            last;
        }
        if ($Flag == 1) {
            my $T = $child->as_trimmed_text;
            $MoshText = $MoshText . " " . $T;
        }
        unshift @kids, $child->content_list;
    }
}
print $MoshText . "\n";

編集

元のテキストが含まれていたオブジェクトを削除することの意味を明確にするため に

「Good Text can be pattern matching」を含むテーブルは、テーブルではなく div にする必要があります

面白いのはオブジェクトなので、このオブジェクトを次のような新しい div オブジェクトに置き換えます

my $new = HTML::Element->new('tag','div');
$new->attr('class', 'MyClass');
$new->push_content('Good Text can be pattern matched');

しかし、テーブルの削除と挿入 $new をどのように見つけますか

きれいな出力

    <div>
      Div where mosh set to start
    </div> 
    <div class ='MyClass'>
      Good Text can be pattern matched
    </div>
    <div class ='AnotherClass' >
      Wanted Text More Wanted Text Yet More Wanted Text
    </div>
    <div mosh="stop">Div where mosh set to stop bellow here is not needed</div>

それがより理にかなっていることを願っています

4

3 に答える 3

2

コードが機能しない理由を理解していると思います。HTML 内のすべての要素のテキスト値を出力しています。要素のテキスト値には、その子孫のすべてのテキスト ノードが含まれているため、いくつかのテキストが複数回表示されています。

HTML ツリーを再帰的に処理する必要がありmoshます。各要素の属性の値をチェックし、それに応じて (既に行っているように) フラグを保持し、フラグが設定されている場合にのみテキスト ノードを表示します。

このプログラムはデモンストレーションします。で文字列を分割することを示しましたが、元のテキストが含まれていたオブジェクトを削除するmatchedことの意味がわかりません。

use strict;
use warnings;

use HTML::TreeBuilder;
use HTML::Element;

my $tree = HTML::TreeBuilder->new->parse_file(*DATA);

my $wanted;
my @mosh_text;
my @nodes = ($tree);

while (@nodes) {

  my $node = shift @nodes;

  if (not ref $node) {
    push @mosh_text, $node if $wanted;
  }
  else {

    my $mosh = lc($node->attr('mosh') // '');
    if ( $mosh eq 'start' or $mosh eq 'stop' ) {
      $wanted = $mosh eq 'start';
    }

    unshift @nodes, $node->content_list;
  }
}

my $mosh_text = "@mosh_text";
print "$_\n" for split/\s*matched\s*/, $mosh_text;

__DATA__
<body>
  <div mosh="start">Div where mosh set to start</div
  <div>
<table>
  <tr>
    <td></td><td</td>
    <th>Good Text can be pattern matched</th>
    <td></td><td</td>
  </tr> 
</table
</div>
<p>

   <p>
      <b>Wanted Text</b>
   <br>
      <p><b>More Wanted Text</b></p>
   <div>
      <p><b>Yet More Wanted Text</b></p>
   </div>
  </p>
<div mosh="stop">Div where mosh set to stop bellow here is not needed</div>

出力

Div where mosh set to start Good Text can be pattern
Wanted Text More Wanted Text Yet More Wanted Text
于 2012-11-27T18:36:17.003 に答える
0

HTML::TreeBuilder を使用して HTML ページを解析しますが、HTML::Element の look_down()/look_up()/right()/left() メソッドを使用して mosh 属性の境界を見つけます。

境界を指定すると、look_up/look_down メソッドを (ツリー ルートではなく境界要素に対して) 使用して、変更するテキストを含む要素を見つけることができます。要素内のテキストを変更すると、ツリー ルートまたはその他の要素から as_HTML メソッドを使用して HTML を作成できます。

したがって、疑似コードでは次のようになります。

$tree = HTML::TreeBuilder->parse($something)
$mstart = $tree->look_down(
                            _tag => "div",
                            class  => "mosh_start"
                           )
###
# 1. now use HTML::Element traversal methods to find the element that contains the text to match

# 2. use the content manipulation methods to change the content

# 3. rewrite the file
$tree->as_HTML().

HTML::TreeBuilderとともにCPAN のHTML::Treeリリースの一部であるHTML::Elementも参照してください。

于 2012-11-27T22:17:57.603 に答える