2010-06-26 3 views
5

나는 다소 독특한 특질을 펄을 배우고 발견 해요 - 무한 동안 계속 그 루프 while 루프 결과에 여러 정규식 조건 중 하나와 일치를 시도 :Perl : while 전역에서 "또는"분리 된 정규식 조건으로 인해 무한 루프가 발생합니까?

#!/usr/bin/perl 

my $hivar = "this or that"; 

while ($hivar =~ m/this/ig || $hivar =~ m/that/ig) { 
     print "$&\n"; 
} 

이 프로그램의 출력입니다 :

this 
that 
that 
that 
that 
[...] 

이유가 궁금합니다.

#!/usr/bin/perl 

my $hivar = "this or that"; 

while ($hivar =~ m/this|that/ig) { 
     print "$&\n"; 
} 

이 제가 발생하고 실제 문제의 단순화, 그리고 내가 실용적인 관점에서이에 관심이있는 동안, 나는 또한 알고 싶습니다이보다 적은 서투른있는 대안이 있습니까 그 뒤에 무엇이이 행동을 촉발시키고 있는지. Google과 호환되지 않는 질문입니다.

감사합니다.

+0

홉스 (hobbes)가 아래에서 잘 설명했지만 Wall, Schwartz 등이 이에 대해서도 설명했습니다. http://perldoc.perl.org/perlretut.html#Global-matching – msw

+0

Regexp :: 패키지를 조립하면 도움이됩니다. http://stackoverflow.com/questions/1478083/how-can-i-efficiently-match-many-different-regex-patterns-in-perl –

답변

16

건은 숨겨진 /g 경기를 계속 시도 할 경우 제어 각 문자열, 각 경기하지 관련 값, 및 pos($string)를 통해 액세스 할 수는있을 것입니다. 무슨 일입니다 :

  1. pos($hivar) 위치 0에서 0, /this/ 일치하고 4. 또는 운영자가 이미 사실이기 때문에 두 번째 경기가 시도되지 않습니다에 pos($hivar)를 재설정합니다. $&이 "this"가되어 인쇄됩니다.
  2. pos($hivar)이 4이면 /this/은 위치 4 이상에 "this"가 없기 때문에 일치하지 않습니다. 실패한 일치는 pos($hivar)을 0으로 재설정합니다.
  3. /that/은 위치 6에서 일치하고 pos($hivar)에서 10을 재설정합니다. $&은 "그"가되어 인쇄됩니다.
  4. pos($hivar)이 10이면 /this/은 위치 10 이상에 'this'가 없기 때문에 일치하지 않습니다. 실패한 일치는 pos($hivar)을 0으로 재설정합니다.
  5. /that/은 위치 6에서 일치하고 pos($hivar)에서 10을 재설정합니다. $&은 "그"가되어 인쇄됩니다.

그리고 단계 4와 5는 무기한 반복됩니다.

엔진에 pos을 실패한 일치로 재설정하지 않도록 지시하는 c 정규 표현식 플래그를 추가하면 제공 한 예제 코드의 문제가 해결되지만보다 복잡한 문제의 이상적인 해결책 일 수 있습니다.

+2

정말 잘 설명되어 있습니다. – Prix

+0

실제로. 좋습니다. 고맙습니다! –

관련 문제