perl regex多个组

问题描述 投票:1回答:2

我正在尝试在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: 

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

regex perl html-parsing screen-scraping
2个回答
1
投票

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

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

你想做两件事:

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

这将导致以下代码:

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

还要注意parsing HTML with regexes is evil,你应该在CPAN上搜索你喜欢的那个模块。


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
© www.soinside.com 2019 - 2024. All rights reserved.