1

入力ファイル:

<TABLE BORDER="7" CELLPADDING="10">
<TR>
<TD>This is a TD cell</TD>
<TD><PRE> sample</PRE></TD>
<TH>This is a TH cell</TH>
</TR>
<TR>
<TH VALIGN="TOP">Text aligned top</TH>
<TH>Image in TH cell with default alignments ---></TH>
<TH><IMG SRC="blylplne.gif" ALT="airplane"></TH>
</TR>
</TABLE>

タグを一致させるの<TD><PRE> sample</PRE></TD>が好きで、一致した場合は、前のタグから結果を取得するのが好きです。<TD>This is a TD cell</TD>

出力:

これはTD細胞です

以下のコードで試しました:

MY $Output = m/<TD.*?\/TD>/;

タグを一致させることはできますが、同じタグを一致させて前のタグから結果を取得することはできません。前もって感謝します。

4

4 に答える 4

1

後戻りする必要があるため、おそらく完全なツリーを構築する必要があると思います。通常は DOM スタイルの HTML パーサー (「参考文献」を参照Mojo::DOM) をお勧めしますが、ツリーを構築する場合は、次のようなものを試してくださいHTML::Tree

編集:

そこで、 でこれを行うことができるかどうかを確認することにしましたがMojo::DOM、かなりうまく機能しました。

#!/usr/bin/env perl

use strict;
use warnings;

use 5.10.0;
use Mojo::DOM;

my $dom = Mojo::DOM->new->xml(1)->parse(<<'HTML');
<TABLE BORDER="7" CELLPADDING="10">
<TR>
<TD>This is a TD cell</TD>
<TD><PRE> sample</PRE></TD>
<TH>This is a TH cell</TH>
</TR>
<TR>
<TH VALIGN="TOP">Text aligned top</TH>
<TH>Image in TH cell with default alignments ---></TH>
<TH><IMG SRC="blylplne.gif" ALT="airplane"></TH>
</TR>
</TABLE>
HTML

my $collection = $dom->find('TR TD');
my $i = -1; # so that first increment makes 0
$collection->first(sub{$i++; /sample/;});
say $collection->[$i-1];

HTML5 は大文字のタグを使用しないため、XML の解析を強制する必要がありますが、残りは自明です。

2012 年 11 月 1 日編集

Mojolicious 3.54 がリリースされたばかりで、Mojo::DOM に新しいnextandpreviousメソッドが追加されました。(この投稿を使用例として使用しました)。つまり、次のことができるようになりました。

say $dom->find('TR TD')->first(qr/sample/)->previous;

上記の例の最後の 4 行ではなく、

于 2012-05-20T17:27:48.487 に答える
0

成熟したhtmlパーサーを使用しないように独自のhtml正規表現を作成しないように注意することがよくありますが、前者がその仕事をする場合もあります。<PRE>このオプションが役立つかどうかを確認してください(タグをもう少し一致させたい場合があります)。

use Modern::Perl;

my $html = <<'html';
<TABLE BORDER="7" CELLPADDING="10">
<TR>
<TD>This is a TD cell</TD>
<TD><PRE> sample</PRE></TD>
<TH>This is a TH cell</TH>
</TR>
<TR>
<TH VALIGN="TOP">Text aligned top</TH>
<TH>Image in TH cell with default alignments ---></TH>
<TH><IMG SRC="blylplne.gif" ALT="airplane"></TH>
</TR>
</TABLE>
html

say $html =~ m|<TD>(.*?)</TD>.*<TD><PRE>|is;

出力

これはTDセルです

于 2012-05-20T16:40:46.463 に答える
0

これは、正規表現にとって本当に良い問題ではありません。1 つの式でできる最善の方法は、両方のセルを一致させ、グループ内の最初のセルの内容を取得することです。例えば

<TD>(.*?)</TD>\s*<TD><PRE> sample</PRE></TD>

何でも別の式に置き換える必要があると思いますが<PRE> sample</PRE>、ここではそれについて十分な情報を提供していません。

より一般的にこれを行う必要がある場合は、実際にドキュメント ツリーをトラバースできる html パーサーを使用することをお勧めします。

于 2012-05-20T08:56:57.160 に答える
0

後読みと先読みを使用して、テキストの前または後に別のテキストがあることをアサートできます。ルックアラウンドはゼロ幅のアサーションであり、何もキャプチャしないことを意味します。

(?<=TD>)[^>]+(?=</TD>\s*<TD><PRE>\s*sample</PRE></TD>)

つまり:

  1. (?<=TD>)・自分のいる位置から後ろを振り返り、タグがあると断言する
  2. [^>]+- タグの末尾以外のすべてに一致
  3. (?=</TD>\s*<TD><PRE>\s*sample</PRE></TD>)- 現在の位置から先を見て、次のテキストが</TD>\s*<TD><PRE>\s*sample</PRE></TD>(終了タグ、オプションの空白文字、および条件)であることを主張します。

この一致の結果は、#2 で一致したテキストです。

于 2012-05-20T15:56:38.360 に答える