2013-02-25 5 views
0

HTML <TR> 태그에서 모든 행 데이터를 추출하는 스크립트를 만들었습니다. 내 HTML 페이지에 30 개의 HTML <TR> 태그가 있습니다. 개수에 따라 코드에서 특정 행 데이터를 가져옵니다. 예를 들어, 5 번째 <tr>...</tr>에 데이터가 필요하다고 가정하면, 내 조건은 if(count =5) {(go inside and get that data)}HTML :: TableExtract를 사용하여 여러 행 추출

입니다.하지만 여기서 내 문제는 선택된 행의 데이터가 한 번에 하나씩 필요하다는 것입니다. 행 5, 6 및 14에 대한 데이터가 필요하다고 가정 해 보겠습니다.

정렬 해 주시겠습니까?

$te = new HTML::TableExtract(count => 0); 
$te->parse($content); 
# Examine all matching tables 
foreach $ts ($te->table_states) { 
    #print "Table (", join(',', $ts->coords), "):\n"; 
    $cnt = 1; 
    foreach $row($ts->rows) { 
     # print " ---- Printing Row $cnt ----\n"; 
     $PrintLine= join("\t", @$row); 
     @RowData=split(/\t/,$PrintLine); 
     $PrintLine =~ s/\r//ig; 
     $PrintLine =~ s/\t//ig; 
     $cnt = $cnt + 1; 
     # if ($PrintLine =~ /Site ID/ig || $PrintLine =~ /Site name/ig){print " Intrest $PrintLine $cnt =====================\n"}; 
     if ($cnt == 14) { 
      $arraycnt = 1; 
      my $SiteID=""; 
      my $SiteName=""; 
      foreach (@RowData) { 
       # print " Array element $arraycnt\n"; 
       chomp; 
       $_ =~ s/\r//ig; 
       $_ =~ s/[\xC3\xA1\xC3\xA0\xC3\xA2\xC3\xA3]//ig; 
       if ($arraycnt== 17) { $SiteID= $_;} 
       if ($arraycnt== 39) { $SiteName= $_;} 
        $arraycnt = $arraycnt + 1; 
      } 
      #$PrintLineFinal = $BridgeCase."\t".$PrintLine; 
      $PrintLineFinal = $BridgeCase."\t".$SiteID."\t".$SiteName; 
      #print "$PrintLineFinal\n"; 
      print MYFILE2 "$PrintLineFinal\n";   
      last; 
     }  
    } 
} 
+0

감사를 제대로 코드를 들여. –

답변

0

몇 가지 제안 : 항상

는 :

use strict; 
use warnings; 

my으로 변수를 선언하도록 강요합니다. 예 :

foreach my $ts ($te->table_states) { 
    my $cnt = 1; 

( warnings은 가장 어리석은 실수에 대해 알려드립니다. strict는 어떤 경우에 더 나은 방법을 사용하도록 요구함으로써 실수를 방지합니다).

여러 위치에서 배열을 통과 할 때 자신의 카운터 변수를 사용하고 있습니다. 당신은 이것을 할 필요가 없습니다. 대신, 직접 원하는 배열 요소를 얻으십시오. 예 : $array[3]을 사용하여 세 번째 요소를 가져옵니다.

Perl은 또한 배열 슬라이스가 원하는 특정 요소를 얻을 수 있도록합니다. @array[4,5,13]은 배열의 다섯 번째, 여섯 번째 및 네 번째 요소를 가져옵니다. 또한

foreach my $row (@{[$ts->rows]}[4,5,13]) 

: 여기

my @rows = $ts->rows; 
foreach my $row (@rows[4,5,13]) #process only the 5th, 6th, and 14th rows. 
{ 
    ... 
} 

이 익명의 배열을 사용하여, 같은 일의 단축 버전입니다 : 대신 그들 모두를 통해 반복, 당신이 원하는 경우에만 행을 처리하기 위해 이것을 사용할 수 있습니다

my @wanted_rows = (4,5,13); 
... 
foreach my $row (@{[$ts->rows]}[@wanted_rows]) 
이 코드는 매우 혼란

:

, 아마 당신은 당신이 다른 코드에서 원하는 행을 정의 할
$PrintLine= join("\t", @$row); 
@RowData=split(/\t/,$PrintLine); 
$PrintLine =~ s/\r//ig; 
$PrintLine =~ s/\t//ig; 

먼저 탭 문자가있는 배열에 합류하고 방금 결합한 배열을 분할하여 배열을 다시 가져옵니다. 그런 다음 줄의 모든 탭 문자를 제거합니다.

나는 모든 코드를 제거하는 것이 좋습니다. 어레이가 필요할 때마다 복사본을 만드는 대신 @$row을 사용하십시오.디버깅을위한 배열 (인쇄해야 할 경우 $PrintLine과 함께 일을 할 것 모두이다, 당신이 직접 배열을 인쇄 할 수 있습니다 이러한 모든 변화와

print @$row; #print an array, nothing between each element. 
print "@$row"; #print an array with spaces between each element. 

를, 코드는 다음과 같이 될 것이다 :

use strict; 
use warnings; 

my @wanted_rows = (4,5,13); 

my $te = new HTML::TableExtract(count => 0); 

$te->parse($content); 
# Examine all matching tables 
foreach my $ts ($te->table_states) { 
    foreach my $row (@{[$ts->rows]}[@wanted_rows]) { 

     s/[\xC3\xA1\xC3\xA0\xC3\xA2\xC3\xA3\r\n]//ig for (@$row); 

     my $SiteID = $$row[16] // ''; #set to empty strings if not defined. 
     my $SiteName = $$row[38] // ''; 
     print MYFILE2 $BridgeCase."\t".$SiteID."\t".$SiteName; 
    } 
} 
0

이 같은 결과에 액세스 할 수 있습니다 :

foreach $ts ($te->table_states) { 
    #you need 14th rows 
    #my 14throws = $ts->rows->[13];#starting with zero! 
    #17th col from the 14th row 
    #my $17colfrom14throws = $ts->rows->[13]->[16]; 
    my $SiteName = $ts->rows->[13]->[38]; 
    my $SiteID = $ts->rows->[13]->[16]; 
    my $PrintLineFinal = $BridgeCase."\t".$SiteID."\t".$SiteName; 
    print MYFILE2 "$PrintLineFinal\n";  
}