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];

您必须强制进行 XML 解析,因为 HTML5 不使用大写标签,但其余部分应该是不言自明的。

编辑 2012 年 11 月 1 日

Mojolicious 3.54 刚刚发布,它为 Mojo::DOM 提供了新的nextprevious方法,这在这里有所帮助。(我用这篇文章作为他们使用的案例)。这意味着,现在您可以执行以下操作:

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

而不是上面示例的最后 4 行。

于 2012-05-20T17:27:48.487 回答
0

对于正则表达式来说,这并不是一个真正的好问题。使用单个表达式可以做的最好的事情是匹配两个单元格并捕获组中第一个单元格的内容。例如

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

我想你需要<PRE> sample</PRE>用另一个表达式替换任何内容,但你没有在这里提供足够的信息。

如果您需要更通用地执行此操作,则使用实际上可以遍历文档树的 html 解析器将是一个更好的选择。

于 2012-05-20T08:56:57.160 回答
0

您可以使用lookbehind 和lookahead 来断言文本在另一个文本之前或之后 - 环视是零宽度断言,这意味着它们不会捕获任何内容:

(?<=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 回答
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 回答