2012-01-15 4 views
0

내가 뭔가를 간과했을지 모르지만, 왜 이상한 행동이 일어나고 있는지 모르겠습니다.Strange Regex Issue

나는 이것이 무의미한 정규식 캡처라는 것을 알고 있지만, 내 질문은 왜 이것이 발생하는지입니다.

<?php 
// < 15 "a" characters returns "aaaaaaaaaaaaaa {" (no matches) 
$code = 'aaaaaaaaaaaaaa {'; 
// 15 "a" characters returns NULL 
$code = 'aaaaaaaaaaaaaaa {'; 

$code = preg_replace('#(a+)+\{#', 'b', $code); 
var_dump($code); 
?> 

정규식에는 \s이 누락되었습니다. 정규식을 #(a+)+\s\{#으로 변경하면 "b"이됩니다. 그런데 NULL 대신 15 자의 "a"문자를 가진 "aaaaaaaaaaaaaaa {"을 얻지 않으십니까? 오류가 발생하면 NULL이 반환되지만 PHP에서는 아무 것도 출력하지 않습니다 (오류 검사가 켜짐).

편집 : 기본 수준까지 문제를 단순화하기 위해 노력하고 있기 때문에

내가 (a+)+을 사용하고있는 이유입니다. 나는 이것을 다음과 같이 시작했다.

공백이 아닌 일련의 문자를 공백 다음에 여는 중괄호를 찍고 싶다. 또한 더블 +를 사용

#([^\s\{\}]+\s*)+\{#msi 

:

this is some text { 

은 그래서 정규식을 사용했다. 더 좋은 방법이 있습니까? 왜 이것이 처음부터 문제를 일으키는 것입니까?

편집 2 : 아래의 답변에서 double +는 많은 역 참조를 유발하므로 피해야합니다. 나는 이것을 위해 [^\s\{\}][^\{\}]*+\{을 선택했다.

+3

범인은 이상한'(a +) +'패턴이어야합니다 - 동일한 패턴의'+'수량 화기를 두 번 사용하는 이유는 무엇입니까? 두 번째'+'를 삭제하면 문제가 해결됩니다. – Jon

+1

'var_dump (preg_last_error())'할 수 있습니까? Jon이 언급 한 문제로 인해 역 추적 제한에 도달했다고 생각합니다 (정규식이 내부 또는 외부 '?'와 일치해야합니까?). – Wrikken

+0

나는 여기에서 일한다. BTW .... Backtrack limit = 1,000,000 – Wrikken

답변

3
<?php 

ini_set('pcre.backtrack_limit',20000); 
$code = 'aaaaaaaaaaaaaaa {'; 
$code = preg_replace('#(a+)+\{#', 'b', $code); 
var_dump($code, preg_last_error()); 

ini_set('pcre.backtrack_limit',1000000); 
$code = 'aaaaaaaaaaaaaaa {'; 
$code = preg_replace('#(a+)+\{#', 'b', $code); 
var_dump($code, preg_last_error()); 

결과 :

NULL 
int(2) 
string(17) "aaaaaaaaaaaaaaa {" 
int(0) 

하지만 당신이 정말로 사용해야 하나 (a+) 또는 (a)+, 모두없는 조합.

+0

그러면 역 추적을 위해 메모리가 부족합니다. 안좋다. +의 탐욕이 모든 "a"문자를 포착하지 않고 멈출 수 있습니까? –

+0

적절한 의미로 정규 표현식을 사용하는 사람을 만나는 것이 좋습니다. –

+0

@AramKocharyan 아니요. 상위 수준 명령문'(a +) + '의 탐욕은 하위 수준'a + '명령문의 탐욕보다 먼저옵니다. –