2011-02-18 4 views
1

몇 주 전에 불규칙한 형식의 데이터 파일을 구문 분석하는 데 문제가 있음을 게시했습니다. 여기에 데이터의 샘플입니다 : 내가 01-021412, 18, 계산 및 후속 시리즈의 모든 숫자를 합계하고, atraso promedio를 저장 추출하는 프로그램이 필요유연한 분할 작성, perl

01-021412 15/02/2007 207,000.00 14,839.00 18  -6  2  6  6  5 16  6  4  4  3 -28 -59 -88 -119 
                -149 -191 -215 -246    
    Atraso Promedio --->  2.88 

는, 그것은이 작업을 반복 할 수 40,000 이상의 entires. 나는 response 매우 도움이 받았으며, 그에서 코드를 쓸 수 있었다 :

use strict; 
use warnings; 

#Create an output file 
open(OUT, ">outFull.csv"); 
print OUT "loanID,nPayments,atrasoPromedio,atrasoAlt,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72\n"; 

open(MYINPUTFILE, "<DATOS HISTORICO ASPIRE2.txt"); 

my @payments; 
my $numberOfPayments; 
my $loanNumber; 

while(<MYINPUTFILE>) 
{ 
    if(/\b\d{2}-\d{6}\b/) 
    { 
     ($loanNumber, undef, undef, undef, $numberOfPayments, @payments) = split; 
    } 
    elsif(m/---> *(\d*.\d*)/) 
    { 
     my (undef, undef, undef, $atrasoPromedio) = split; 
     my $N = scalar @payments; 
     print "$numberOfPayments,$N,$loanNumber\n"; 

     if($N==$numberOfPayments){ 

     my $total = 0; 
     ($total+=$_) for @payments; 

     my $atrasoAlt = $total/$N; 

     print OUT "$loanNumber,$numberOfPayments,$atrasoPromedio,$atrasoAlt,",join(',', @payments),"\n"; 
     } 
    } 
    else 
    { 
     push(@payments, split); 
    } 
} 

은이 항목의 약 50 %가이 '*'으로는 다음을 포함한다는 사실을 제외하고 잘 작동 것을 :

* 01-051948 06/03/2009 424,350.00 17,315.00 48  0  6 -2  0 21 10  9 13 10  9  7 13  3  4 
                 12 -3 14  8  6 
     Atraso Promedio --->  3.02 

별표는 프로그램이 분할 패턴을 방해하여 잘못된 변수 할당을 초래하기 때문에 프로그램이 실패하게 만듭니다. 지금까지는 입력 데이터 파일에서 별표를 제거하여이 문제를 해결했지만 프로그램을 통해 실제로 이러한 대출을 생략했다는 사실을 알았습니다. 별표가 있거나없는 항목을 처리하도록 스크립트를 수정하는 경제적 인 방법이 있습니까?

항목에 별표가 포함되어있는 경우이 사실을 출력 데이터에 기록하고 싶습니다. 문 정규식가 '*'를 차지, 그래서 우리가 어떻게 수정에 대한되지 않을 경우 사전에

많은 감사,

+0

친애하는 모든 사람들에게 감사드립니다. 불행히도, 나는 그들 각각을 시도했지만 아무도 효과가 없었다. 또한 별표가 공백으로 스왑 된 새 입력 파일을 만든 다음 별도의 프로그램에서 진행중인 대출을 식별하여 문제를 해결하려고했습니다.어떤 이유로, Perl 스크립트는 공백으로 대체 된 별표로 대출을 건너 뜁니다. 다른 아이디어는 놀랄 것입니다. 감사! – Aaron

답변

0

아론은 그래서 처음처럼 보인다. 내 perl 정규식 skillz 조금 녹슨, 참고 이것은 시험되지 않습니다.

if(/(?:\*)?\b\d{2}-\d{6}\b/) 

*

난 그냥 것을 사용

(?:)\*는 "이 함께 그룹을하지만, 그것을 저장하지 마십시오"를 의미, 우리가 탈출 할 수 있도록 "0 번 이상"을 의미 수정이다 그래서 while 루프의 시작 부분에서 동시에

0

의 공간과 * 모두에 ?을 적용 할 수 있습니다,이 시도 :

... 
while(<MYINPUTFILE>) 
{ 
    my $asterisk_exists = 0; 
    if (s/^\* //) { 
     $asterisk_exists = 1; 
    } 
... 

s/// 함수를 사용하여 별표를 제거하는 것 외에도 별표가 첫 번째 위치에 있었는지 여부도 추적합니다. 별표를 제거하면 나머지 스크립트가 정상적으로 작동합니다.

1

사용 중간 배열 :이 외에도, 당신은, 3 개 인수는 열 어휘 파일 핸들 및 테스트를 사용해야

while(<MYINPUTFILE>) { 
    s/^\s*\*\s*//; 

    if(/\b\d{2}-\d{6}\b/) { 
     ($loanNumber, undef, undef, undef, $numberOfPayments, @payments) = split; 
    ...  

: 그리고 당신은 분할을하기 전에 별표를 폐기 할 수

my $has_asterisk; 

# ... 

if(/\b\d{2}-\d{6}\b/) 
{ 
    my @fields = split; 
    $has_asterisk = $fields[0] eq '*'; 
    shift @fields if $has_asterisk; 
    ($loanNumber, undef, undef, undef, $numberOfPayments, @payments) = @fields; 
} 
1

실패로 인해 열린다.

my $file = 'DATOS HISTORICO ASPIRE2.txt'; 
open my $MYINPUTFILE, '<', $file or die "unable to open '$file' for reading : $!";