2008-11-14 4 views
5

나는 힘든 시간 반드시이 펄의 QR을 사용하는 경우 {} 내가 일반적으로 탈출 문자의 무수를 포함하는 멀티 라인 텍스트 미리 컴파일 된 정규식을 만들려고 해요Perl 미리 컴파일 된 정규식에서 어떤 문자를 벗어나야합니까?

를 구성 이스케이프 어떤 문자를 결정하는 데 (# *.> : []) 또한 미리 컴파일 된 다른 정규 표현식을 포함합니다. 또한 테스트 목적으로 최대한 엄격하게 일치시켜야합니다.

my $output = q{# using defaults found in .config 
* 
* 
Options: 
    1. opt1 
> 2. opt2 
choice[1-2?]: }; 

my $sc = qr{(>|\s)}smx; 
my $re = qr{# using defaults found in .config 
* 
* 
Options: 
$sc 1. opt1 
$sc 2. opt2 
choice[1-2?]: }mx; 

if ($output =~ $re) { 
    print "OK!\n"; 
} 
else { 
    print "D'oh!\n"; 
} 

오류 :

(오 D' 출력) 실패한 경기에서 별표 결과를 탈출하려고
Quantifier follows nothing in regex; marked by <-- HERE in m/# using defaults found in .config 
* <-- HERE 
* 
Options: 
(?msx-i:(>|\s)) 1. opt1 
(?msx-i:(>|\s)) 2. opt2 
choice[1-2?]:/at ./so.pl line 14. 

. 성가신 다른 문자를 이스케이프하려고해도 일치하지 않습니다. 탈출 할 수있는 여러 가지 조합을 계속 시도 할 수 있지만 여기에는 많은 변형이 있으며 누군가가 통찰력을 제공 할 수 있기를 희망합니다.

답변

14

qr //에 대한 구분 기호를 이스케이프 처리해야하며 리터럴로 사용할 정규식 메타 문자를 이스케이프 처리해야합니다. 그것들을 리터럴 *로 바꾸려면 *가 정규 표현식이므로 대문자로 이스케이프해야합니다.

여기에 추가 된 다양한 정규식 플래그가 있습니다./m은 문자열 시작 또는 끝 (^, $) 앵커를 사용하지 않기 때문에 아무 것도하지 않습니다. 와일드 카드를 사용하지 않기 때문에/s는 아무 것도하지 않습니다. 메타 문자./x는 정규 표현식의 공백을 모두 무의미하게 만들고 #을 사용하여 해당 행을 정규 표현식 주석으로 변환합니다.

정규식 플래그가 제거로 당신이 원하는 것입니다 적절한 상황이 탈출 :

데미안 콘웨이는 항상 정규 표현식에에이 옵션을 넣어 펄 모범 사례 사람들을 알 수 있지만
my $sc = qr{(>|\s)}; 

my $re = qr{# using defaults found in \.config 
\* 
\* 
Options: 
$sc 1\. opt1 
$sc 2\. opt2 
choice\[1-2\?]: }; 

, 당신이 지금보고 왜 그가 틀렸어. 자신이하는 일을 원할 때만 추가해야하며, 자신이하는 일을 알면 추가해야합니다. :) 다음은/x를 사용하려는 경우 수행 할 작업입니다. 리터럴 공백을 이스케이프해야하고, 어떻게 든 라인 끝을 표시해야하며 리터럴 # 문자를 이스케이프 처리해야합니다. 무엇 전에 읽을 수 있었다 지금 엉망이다

 
my $sc = qr{(>|\s)}; 
my $eol = qr{[\r\n]+}; 

my $re = qr{\# \s+ using \s+ defaults \s+ found \s+ in \s+ \.config $eol 
\*     $eol 
\*     $eol 
Options:    $eol 
$sc \s+ 1\. \s+ opt1 $eol 
$sc \s+ 2\. \s+ opt2 $eol 
choice\[1-2\?]: \s+ 
}x; 

if ($output =~ $re) { 
    print "OK!\n"; 
} 
else { 
    print "D'oh!\n"; 
} 
+0

아아! 내 자신의 'x'와 'x'에 대한 이해는 현실과 반대였다. 그러므로 $ re에서 's'가 누락되었습니다. 하지만 네, 여기 PbP도 비난합니다. :) –

+0

책은 옵션이 무엇을하는지 설명하고 사용하는 이유에 대해 설명합니다. 책을 비난 할 수는 없습니다. :) –

+0

나는 책을 비난 할 수있다. "항상/x 플래그 사용"(p 236) 및 "항상/m 플래그 사용"(p 237)이라고 나와 있습니다."항상"권고안은 잘못되었습니다. –

7

당신이 정말 Expect입니다 원하는 것 같은데,하지만 당신은 대부분 즉시 찾고있는 것은 정규식에 특별한 의미가있는 모든 문자를 빠져 나간다 quotemeta 연산자입니다. 브라이언 말했듯이

은 구분 기호 및 정규식 메타 문자를 탈출해야 .[$()|*+?{\

+0

실제로 Expect와 Test :: More와 함께 사용됩니다. 예를 들어 코드를 분석하면됩니다. –

2

, 당신은 최소한 탈출해야합니다 (이 경우 }에서)를 맺다 문자뿐만 아니라, 직접 (그러나) 귀하의 질문에 대답하려면 . qr//x (현재)을 사용할 때 공백 문자와 # (주석 표시 자임)를 이스케이프해야합니다. 실제로 여기서 /x을 사용하고 싶지는 않습니다. 은 영숫자가 아닌 문자를 이스케이프 처리하면 안전합니다.

관련 문제