2010-02-14 2 views
13

저는 정규식을 가지고 있습니다 :Perl 정규 표현식의 캡처를 별도의 변수에 저장하려면 어떻게해야합니까?

/abc(def)ghi(jkl)mno(pqr)/igs 

각 괄호의 결과를 각 괄호에 하나씩 3 개의 다른 변수로 어떻게 포착 할 수 있습니까? 지금은 하나의 배열을 사용하여 모든 결과를 캡처하지만 순차적으로 나옵니다. 그런 다음 구문 분석을해야하며 목록이 커질 수 있습니다.

@results = ($string =~ /abc(def)ghi(jkl)mno(pqr)/igs); 
+0

패턴 일치 횟수를 계산 하시겠습니까? 그게 나에게 맞는 것 같아 ... – Zaid

+0

나는 성냥을 처리해야한다. – Incognito

답변

14

귀하의 질문은 나에게 조금 모호하지만, 나는 당신이 이런 식으로 뭔가를하고 싶은 생각 :

my (@first, @second, @third); 
while(my ($first, $second, $third) = $string =~ /abc(def)ghi(jkl)mno(pqr)/igs) { 
    push @first, $first; 
    push @second, $second; 
    push @third, $third; 
} 
+0

재미있다. 그것이 효과가있을 것이라고 확신합니까? – joejoeson

+3

약간 길다. 캡처 할 때 뒷쪽 참조를 사용할 수 있습니다 – ghostdog74

+4

ghostdog74 : 맛의 문제입니다. 변수 $ first와 $ second의 이름을 실제로 지정하면 $ 1과 $ 2를 실제로 사용할 수 있습니다. 그러나 설명적인 이름을 지정하면 읽기 쉽도록 향상시킬 수 있습니다. –

0

당신은 세 가지 다른 정규식의 각 특정 그룹에 초점을 맞추고있을 수 있습니다. 분명히, 당신은 정규식에있는 다른 배열에 다른 그룹을 할당하고 싶습니다,하지만 당신의 유일한 옵션은 정규 표현식을 분할하는 것입니다 생각합니다. 괄호를 캡처 할 때

2

@OP, 당신은 변수를 $ 1, $ 2 .... 이러한 역 참조

$string="zzzabcdefghijklmnopqrsssszzzabcdefghijklmnopqrssss"; 
while ($string =~ /abc(def)ghi(jkl)mno(pqr)/isg) { 
    print "$1 $2 $3\n"; 
} 

출력

$ perl perl.pl 
def jkl pqr 
def jkl pqr 
+3

그의 g 수정 자 사용에 유의하십시오. 그는 세계적인 경기를하고 있기 때문에 여러 경기를 저장하고 싶어한다고 가정합니다. –

+2

은 또한 $ 1 등은 "역 참조"아니다, 그들은 캡처입니다. 그러나 괄호와 역 참조는 * 관련 *합니다. – jrockway

3

이 보일 것이다 일을하는 또 다른 방법을 사용할 수 있습니다 ghostdog74의 답변과 같지만 해시 참조를 저장하는 배열을 사용하는 경우 :

my @results; 
while($string =~ /abc(def)ghi(jkl)mno(pqr)/igs) { 
    my ($key1, $key2, $key3) = ($1, $2, $3); 
    push @results, { 
     key1 => $key1, 
     key2 => $key2, 
     key3 => $key3, 
    }; 
} 

# do something with it 

foreach my $result (@results) { 
    print "$result->{key1}, $result->{key2}, $result->{key3}\n"; 
} 

여기에 단일 데이터 구조를 사용하고 멋진 읽기 가능 루프가 있습니다.

5

5.10을 시작으로, 당신은뿐만 아니라 named capture buffers를 사용할 수 있습니다

#!/usr/bin/perl 

use strict; use warnings; 

my %data; 

my $s = 'abcdefghijklmnopqr'; 

if ($s =~ /abc (?<first>def) ghi (?<second>jkl) mno (?<third>pqr)/x) { 
    push @{ $data{$_} }, $+{$_} for keys %+; 
} 

use Data::Dumper; 
print Dumper \%data; 

출력 :

$VAR1 = { 
      'first' => [ 
         'def' 
        ], 
      'second' => [ 
         'jkl' 
         ], 
      'third' => [ 
         'pqr' 
        ] 
     };

이전 버전의 경우, 각 촬영을 위해 줄을 추가하는 것을 피한다 다음을 사용할 수 있습니다 버퍼 :

#!/usr/bin/perl 

use strict; use warnings; 

my $s = 'abcdefghijklmnopqr'; 

my @arrays = \ my(@first, @second, @third); 

if (my @captured = $s =~ /abc (def) ghi (jkl) mno (pqr) /x) { 
    push @{ $arrays[$_] }, $captured[$_] for 0 .. $#arrays; 
} 

use Data::Dumper; 
print Dumper @arrays; 

출력 :

$VAR1 = [ 
      'def' 
     ]; 
$VAR2 = [ 
      'jkl' 
     ]; 
$VAR3 = [ 
      'pqr' 
     ];

하지만 관련 데이터를 단일 데이터 구조로 유지하는 것이 좋으므로 해시를 사용하는 것이 가장 좋습니다. 변수의 이름이 정말 버퍼의 이름은 중요하지 않을 경우 firstsecond는 등, 또는 만 위해, 당신은 사용할 수 않는 경우,

my %data; 
my @keys = qw(first second third); 

if (my @captured = $s =~ /abc (def) ghi (jkl) mno (pqr) /x) { 
    push @{ $data{$keys[$_]} }, $captured[$_] for 0 .. $#keys; 
} 

을 또는이 그러나, 보조 배열을 필요로하지 않습니다 :

my @data; 
if (my @captured = $s =~ /abc (def) ghi (jkl) mno (pqr) /x) { 
    push @{ $data[$_] }, $captured[$_] for 0 .. $#captured; 
} 
+0

당신은 단지 첫 번째 예에서 깊은 사본을하려고합니까? 나는 Storable의 dclone을 꺼냈다. 어느 쪽이든, 또는 당신의 예제는'$ data'에 저장 한 값을 만들기 위해 루핑을 필요로합니다. :) 내가 각 라인은 당신에게'first'과' '초과'third' 값을 제공하는 파일을 구문 분석하고 자신의 배열에 그 값을 저장하는 생각 –

+0

@ 브라이언. 레온 Timmerman의 예와 비교 (http://stackoverflow.com/questions/2259784/how-can-i-store-captures-from-a-perl-regular-expression-into-separate-variables/2259795#2259795) –

관련 문제