2009-08-18 5 views
3

일부 텍스트의 "사이"를 잡는 코드가 있습니다. , 구체적으로는 foo $someword과 그 다음은 foo $someword입니다.Perl 정규 표현식이 무한 루프를 일으키는 이유는 무엇입니까?

그러나 처음에는 "사이"에 갇혀서 어떻게 든 내부 문자열 위치가 증가하지 않습니다.

입력 데이터는 여기 저기에 개행 문자가있는 텍스트 파일로, 관련성이 적지 만 인쇄가 쉬워집니다.

my $component = qr'foo (\w+?)\s*?{'; 

while($text =~ /$component/sg) 
{ 
    push @baz, $1; #grab the $someword 
} 

my $list = join("|", @baz); 
my $re = qr/$list/; #create a list of $somewords 

#Try to grab everything between the foo $somewords; 
# or if there's no $foo someword, grab what's left. 

while($text=~/($re)(.+?)foo ($re|\z|\Z)/ms) 
#if I take out s, it doesn't repeat, but nothing gets grabbed. 
{ 
# print pos($text), "\n"; #this is undef...that's a clue I'm certain. 
    print $1, ":", $2; #prints the someword and what was grabbed. 
    print "\n", '-' x 20, "\n"; 
} 
+2

는하지 마십시오 당신이 원하는 "/ g "수정 자도 두 번째 루프에서? – jrockway

+0

\ z와 \ Z는 필요하지 않습니다. \ Z는 \ z를 포함합니다. \ z –

+0

배열을 잡는 것이 아니라 (그/g가 반환 할 것입니다) 텍스트를 걷고 있습니다. 그러나/g는 최종 출력 문제에 영향을주지 않습니다. 난 노력 했어. :-) –

답변

4

업데이트 :

use strict; 
use warnings; 

use File::Slurp; 

my $text = read_file \*DATA; 

my $marker = 'foo'; 
my $marker_re = qr/$marker\s+\w+\s*?{/; 

while ($text =~ /$marker_re(.+?)($marker_re|\Z)/gs) { 
    print "---\n$1\n"; 
    pos $text -= length $2; 
} 

__DATA__ 
foo one { 
one1 
one2 
one3 

foo two 
{ two1 two2 
two3 two4 } 

that was the second one 

foo three { 3 
foo 3 foo 3 
foo 3 
foo foo 

foo four{} 

출력 : 한 번 더 업데이트를 추출 할 텍스트 내부에서 발생하는 'foo' 다루는

 
--- 

one1 
one2 
one3 


--- 
two1 two2 
two3 two4 } 

that was the second one 


--- 
3 
foo 3 foo 3 
foo 3 
foo foo 


--- 
} 
+0

정보, 예. {그리고 그 다음 foo 전에 모든 것을 찾고 있습니다. –

+0

그거야. pos $ text - = 3이 없으면 첫 번째와 마지막을 반환합니다. 나는 솔루션이 왜 효과가 있고 왜 내 문제가 헷갈 렸는지 걱정된다. 생각? –

+0

'(? : foo | \ Z)'를 찾으려면 foo가 있으면'pos $ text'를'foo'의 길이만큼 전진시킵니다. 따라서'pos $ text'가 현재 위치보다 3 문자 앞의 다음'foo '이전의 위치로 재설정되지 않는 한, 다음'foo' 다음에 다음 일치가 시작됩니다. 이미 문자열의 끝 부분에 도달했다면 이것은 중요하지 않습니다. –

관련 문제