2017-01-27 4 views
1

나는 약간의 펄 스크립트를 사용하고 있지만, 파일을 읽는 동안 그리고 정규 표현식을 반복하는 것보다 문제가있다.펄 파일 읽기 및 RegEx 일치

특히 파일이 여러 줄로되어 있고 각 줄마다 몇 가지 값을 추출해야합니다. 더 잘 이해하기 위해 예제를 게시합니다.

이 파일의 샘플 라인은

I가 일치 할 필요
  1A OCC OCC 4B 5B 6B 7B 8B 9A 
     OCC OCC 12B 13B 14B OCC 16B 17B 18B OCC OCC 

첫 번째, 두 번째, N .. separetly 라인 : 1A 4B 5B 6B 7B ...

excecpt OCC.

my $path="file.txt"; 

open (my $fh, "<", $path); 

while(my $line = <$fh>) 
{ 
    for ($line =~/(\d{1,2}[A|B|C])/){ 
     print " $1"; 
} 
} 

제가 라인에 유사한 제 occurance에만 매치 얻어진 결과 :

는이 코드를 썼다. 1A 12B

어떻게 모든 행을 읽고 내용을 올바르게 일치시킬 수 있습니까?

인쇄 결과는 내 디버깅 테스트 용입니다.

답변

2

쓴 내용은 번을 번 캡처하고 중지합니다. 따라서 for 루프는 (line =~ ...) 안에있는 하나의 숫자를 넘습니다.

대신 /g수정 자을 사용하면 계속 일치하는 모든 일치 항목을 찾을 수 있습니다. 당신은 배열에 다음 운영자가 리스트 문맥에 있음을 할당하고 그것을 반환하는 경우 모든 사용자가 전체 경기를 가지고 있기 때문에 여기에 당신이 캡처 괄호가 필요하지 않습니다

my @matches = $line =~ /\d{1,2}[A-C]/g; 

일치합니다. 의심 할 때 그들을 추가하십시오. 숫자 뒤에 숫자가 필요하면 문자 대신 /\d+\w+/g을 사용할 수 있습니다.

몇 가지 의견을 보내고 싶습니다.

  • 항상 use warnings;로 프로그램을 시작하고하십시오 use strict;

  • 항상 전부 open

use warnings 'all'; 
use strict; 
use feature qw(say); 

my $path="file.txt"; 

open my $fh, "<", $path or die "Can't open $path: $!"; 

while (my $line = <$fh>) 
{ 
    my @matches = $line =~ /(\d{1,2}[A-C])/g; 

    say "@matches"; 
} 

close $fh; 
같은 항상 확인 전화
2

정규식의 모든 일치 항목을 일치 시키려면 /g 수정자를 사용해야합니다.

또한 for의 인수가 목록 컨텍스트에서 평가되므로 모든 일치 항목을 한 번에 반환하므로 $1을 사용하면 각 일치 항목에 대해 동일한 값 (마지막 항목)이 반환됩니다. 이 경기의 긴 목록을 할 필요없이, 일치하는 부품 하나 하나를 반환로 대신 while와 일치를 통해 루프에 공통의,

for ($line =~ /(\d{1,2}[ABC])/g) { 
    print " $_"; 
} 

을하지만 :하지만 당신은 대신 루프 변수를 사용할 수 있습니다.

while ($line =~ /(\d{1,2}[ABC])/g) { 
    print " $1"; 
} 

참고 : 귀하의 입력 |를 포함하지 않는, 그래서 문자 클래스에서 제거 여기에서는 루프 조건이 스칼라 문맥에서 평가되는 한, $1이 필요합니다.