1

我正在尝试在 perl 中进行屏幕抓取,并将其归结为一组表格元素。

字符串:

<tr>
        <td>10:11:00</td>
        <td><a href="/page/controller/33">712</a></td>
        <td>Start</td>
        <td>Finish</td>
        <td>200</td>
        <td>44</td>

代码:

if($item =~ /<td>(.*)?<\/td>/)
            {
                print "\t$item\n";
                print "\t1: $1\n";
                print "\t2: $2\n";
                print "\t3: $3\n";
                print "\t4: $4\n";
                print "\t5: $5\n";
                print "\t6: $6\n";
            }

输出:

1: 10:11:00
2: 
3: 
4: 
5: 
6: 

我尝试了多种方法,但无法获得预期的结果。想法?

4

2 回答 2

5
use strict;
use warnings;

my $item = <<EOF;
<tr>
        <td>10:11:00</td>
        <td><a href="/page/controller/33">712</a></td>
        <td>Start</td>
        <td>Finish</td>
        <td>200</td>
        <td>44</td>
EOF

if(my @v = ($item =~ /<td>(.*)<\/td>/g))
{
  print "\t$item\n";
  print "\t1: $v[0]\n";
  print "\t2: $v[1]\n";
  print "\t3: $v[2]\n";
  print "\t4: $v[3]\n";
  print "\t5: $v[4]\n";
  print "\t6: $v[5]\n";
}

或者

if(my @v = ($item =~ /<td>(.*)<\/td>/g))
{
  print "\t$item\n";
  print "\t$_: $v[$_-1]\n" for 1..@v;
}

输出:

1: 10:11:00
2: <a href="/page/controller/33">712</a>
3: Start
4: Finish
5: 200
6: 44
于 2012-12-11T02:49:13.477 回答
1

代码的行为与您告诉它的完全一样。这就是发生的事情:

您只匹配了一次正则表达式。它确实匹配,并$1用第一个(也是唯一一个!)捕获缓冲区的值填充了变量。匹配返回“true”,并执行 if 分支中的代码。

你想做两件事:

  1. /g修饰符匹配。这会全局匹配,并尝试返回字符串中的每个匹配项,而不仅仅是第一个匹配项。
  2. 在列表上下文中执行正则表达式,这样您就可以将捕获缓冲区保存到数组中

这将导致以下代码:

if ( my @matches = ($item =~ /REGEX/g) ) {
  for my $i (1 .. @matches) {
    print "$i: $matches[$i-1]\n";
  }
}

还请注意,使用正则表达式解析 HTML 是邪恶的,您应该在 CPAN 中搜索您喜欢的为您执行此操作的模块。

于 2012-12-11T02:49:49.377 回答