2012-12-04 2 views
3

정규 표현식에서 예상치 못한 결과가 발생합니다. 이는 네임 스페이스의 클래스 이름을 대체하기위한 것입니다. 교체 작업이 두 번 발생하여 대체되는 클래스 이름이 복제됩니다 (아래 예 참조).preg_replace double replacement

는 사실은 실제로 더 정확하게 내가 원하는 것에 대해 오히려 0 이상 (*)보다 1 이상 (+)와 일치하는 등록의 전을 변경하여 문제를 해결했습니다.

그러나 처음에는 문제가 발생하는 이유에 대해 다소 혼란 스럽습니다. 여기

문제의 예는 다음과 같습니다
components\groups\GroupsAccess 

이 가능인가요

$classns = 'components\groups\GroupsController'; 
$newclass = 'GroupsAccess'; 
$classns = preg_replace('/[^\\\\]*$/', $newclass, $classns); 
echo $classns; 

결과

components\groups\GroupsAccessGroupsAccess 

예상 * 그 단어 경계 또는 뭔가 일치한다 자연?

혼란스러운 부분은 동일한 정규 표현식을 사용하는 preg_match가 하나의 결과 만 표시한다는 것입니다. 따라서 preg_match가 정규식을 실행하는 방법과 관련이있는 것으로 보입니다.

preg_match('/[^\\\\]*$/', $classns, $m); 
var_dump($m); 

*는 단어 경계와 일치하지 않는

array(1) { [0]=> string(12) "GroupsAccess" } 
+2

'preg_match_all'은 무엇을 보여줍니까? 'preg_match'_always_는 최대 하나의 일치를 보여줍니다. –

+0

@JanDvorak 잘 잡으세요. 그것은 두 경기를 보여줍니다. –

+0

왜 str_replace를 사용하지 않습니까? – Evert

답변

5

결과, 그것은 빈 문자열 일치한다.

내 발현은 제

성분

GroupsController\기를 \ 매칭에 있고 $는 위치 일치하는 앵커이며 그 문자열의 끝 (이전 인 또는 문자열의 끝 앞에 \n).

첫 번째 일치 후에 정규 표현식 파서의 위치는 마지막 "r"다음에 문자열의 끝 앞에서 정규 표현식을 다시 일치 시키려고합니다. 그리고 / (빈 문자열)과 문자열 끝에 더 많은 일치 ==> 0 번을 찾습니다.

다음으로 이동하여 문자열의 끝을 인식하고 끝냅니다.

>>> re.findall('a*$', 'a') 
['a', ''] 

그래서 펄을 수행합니다 :

preg_match_all('/a*$/', 'a', $m);` 

파이썬이 같은 동작이 있습니다

+0

나는 "Then it goes on"부분을 놓쳤다. (일치하는 부분이 없으면 포인터는 한 문자 더 앞당겨진다.) 이제 완벽하게 이해됩니다. 감사. –

+0

['첫 번째 일치 항목이 발견 된 후 후속 검색은 마지막 일치 항목의 끝에서부터 계속됩니다.]] (http://php.net/manual/en/function.preg-match-all.php) 비어 있습니다. 예외와 일치하거나 오해했습니다. –

+0

@JanDvorak, "빈 일치"란 무엇입니까? 그것은 정의 된 패턴이 발견 되었기 때문에 일치합니다 (물론 그것은 빈 문자열입니다). 정규식 엔진은 마지막으로 발견 된 일치 항목 이후에 항상 검색을 계속합니다. – stema

2

이는 두 경기를 보여주고, 그것을 좁히는 것은

>>> my @m = 'a' =~ /a*$/g; 
>>> foreach (@m) { print "$_\n"; } 
a 
<blank> 

이 정규식 나타납니다 엔진은 'a'과 그 뒤에 오는 빈 문자열 ''과 일치합니다. 기술적으로 이것은 놀랍지 만 정확합니다. 'a'은 검색 문자열 끝에 고정되어있는 문자열이며 ''입니다.

일치하는 기본 규칙 중 하나는 일치가 겹치지 않는다는 것입니다. 일치가 발견되면 regex 엔진은 이전 일치 항목의 끝에서 다음 일치 항목을 계속 검색합니다. 예상하지 못한 점은 앵커 $을 다시 사용할 수 있다는 것입니다. 아마도 실제 너비가 아닌 어썰트이고 실제 부분 일치가 아니기 때문입니다.