2012-12-11 51 views
1

我想在perl中做一個屏幕抓取,並將其歸結爲一個表元素數組。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: 

我試着多的東西,但無法得到預期的結果。想法?

+0

你的「預期成果」是什麼? –

+2

停止使用正則表達式來解析HTML。 –

+3

請不要使用正則表達式來解析HTML。正則表達式不足以完成這項工作。使用適當的DOM解析器。 http://htmlparsing.com/perl.html有關於如何從Perl中完成的示例。 –

回答

1

代碼的行爲完全爲你告訴它。這是發生了什麼事情:

你匹配正則表達式只有一次。它確實匹配,並用第一個(也是唯一的!)捕獲緩衝區的值填充$1變量。該匹配返回「true」,並執行if分支中的代碼。

你想要做的兩件事情:

  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 [email protected]; 
} 

輸出:

1: 10:11:00 
2: <a href="/page/controller/33">712</a> 
3: Start 
4: Finish 
5: 200 
6: 44