2013-03-15 2 views
0

저는 Perl과 regex에 많은 경험이 있습니다. 그러나 이것은 나를 미치게 만들고있다, 나는 단지 그것에 대한 답을 찾을 수 없으며 나는 그것에 대한 이유도 볼 수 없다. 다음 코드를보고하십시오 : 당신이 볼 수 있듯이대괄호를 구분 기호로 사용할 경우 Perl 정규식이 작동하지 않습니다. 왜?

Yes 
No 
Yes 

, 나는 변화하고있어 유일한 것은 정규식 구분 기호, 그리고 표현이 작동하지 않습니다 :

my $str = 'Hello[world]'; 

say $str =~ m/\w+\[.*?\]/ ? 'Yes' : 'No'; 
say $str =~ m[\w+\[.*?\]] ? 'Yes' : 'No'; 
say $str =~ m(\w+\[.*?\]) ? 'Yes' : 'No'; 

이의 출력은 구분 기호가 대괄호 일 때 예상대로.

다른 사람이 왜 일치하지 않는지 설명해주세요. 사전에

감사합니다,

시스코

+1

구분 기호로'[]'또는'()'를 사용해서 혼동하지 마십시오. (왜냐하면 그들은 정규 표현식에서 특별한 의미를 갖기 때문이다.) – nhahtdh

+0

대괄호를 두 번 이스케이프 처리해야 할 것 같네요.하지만 그럴 수 있는지 여부는 확실하지 않습니다. 인터프리터는 리터럴 괄호, 문자 클래스 및 구분 기호를 어떻게 구분합니까? – Bergi

+0

@Bergi : [인용 된 구문 구문 분석에 대한 세부 정보] (http://perldoc.perl.org/perlop.html#Gory-details-of-parsing-quoted-constructs) – nhahtdh

답변

6

B::Deparse 모듈이 구조에 관해서 : 당신이 볼 수 있듯이, 당신의 정규식에서 [ ]의 이스케이프는 펄이 지금 해석 것을 의미

$ perl -MO=Deparse foo.pl 
my $str = 'Hello[world]'; 
say $str =~ /\w+\[.*?\]/u ? 'Yes' : 'No'; 
say $str =~ /\w+[.*?]/u ? 'Yes' : 'No'; 
say $str =~ /\w+\[.*?\]/u ? 'Yes' : 'No'; 
foo.pl syntax OK 

구분 문자가 아닌 메타 문자로 사용됩니다. 두 단계의 탈출이 필요합니다. \\이 리터럴 백 슬래시로 해석되기 때문에 나는 확신 할 수 없습니다.

정상적인 정규식에서 대괄호 []은 메타 문자 상태를가집니다. 따라서 문자 그대로 일치 시키려면 탈출해야합니다. 구분 기호로 사용하는 경우 다른 메타 문자 상태를 추가하십시오. 구분 문자이기도합니다. 따라서 메타 문자 상태를 모두 이스케이프 처리해야합니다. 의도 한대로이 작동

: 물론

say $str =~ m[\w+\Q\[\E.*?\Q\]\E] ? 'Yes' : 'No'; 

, 여기에 교훈은 현명하게 구분 기호를 선택하는 것입니다.

+0

예, 보았습니다. 하지만 왜? 그들은 똑같은 방식으로 3 번 이스케이프됩니다. 자, 어떻게 그들을 피할거야? –

+1

@FranciscoZarabozo 내가 대답 한대로 : 당신은 두 단계의 도피가 필요합니다. '[]'괄호는 구분 기호로 사용할 때 두 개의 서로 다른 메타 상태를가집니다. – TLP

+0

좋아, 그럼, 당신이 그들을 한 번 촉각 때, 정확히 당신은 scaping 무엇입니까? Deparse에 따르면, 마치 전혀 벗어나지 않는 것처럼 끝납니다. –

0

일치를 수행하기 전에 [<]> (또는 다른 유사한 대체)으로 바꾸어보십시오.

+0

음 ... 실제 문제가 아니 었습니다. 어떻게 해결해야할지 몰랐습니다. 나는 그저 통역자의 행동에 대한 이유를 이해하고 싶었다. 그러나 어쨌든 고마워. :-) –

관련 문제