2011-04-22 5 views
3

정규 표현식 코드에 문제가 있습니다. 문제는 다음과 같습니다. 모든 "foo"값을 "()"대신 바꾸려고합니다. 예 :() 사이의 모든 "foo"를 대체하십시오.

try foo foo-foo (try foo inside , foo foo foofoo) 

괄호 사이의 모든 "foo"문자열을 "boo"로 바꾸고 싶습니다.

$str = preg_replace('/foo(?=[^()]*\))/', 'bar', $str); 

근무 예 : 괄호 "유효"입니다 가정

+7

정규 표현식 코드는 어디에 있습니까? –

답변

7

, 당신은 사이에 (없이 ) 다음에 모든 foo들, 대체 할 수 http://ideone.com/xezU7

또 다른 옵션을, 또한 가정 없음 중첩 된 쌍은 "(...)" 토큰과 일치하고 콜백을 사용하지만 과도한 힘을 사용할 수 있습니다.

콜백 메서드 :

function replace_foo($matches) { 
    return str_replace('foo', 'bar', $matches[0]); 
} 

사용 :

$str = preg_replace_callback("/\([^()]*\)/","replace_foo", $str); 

근무 예 : 당신은 루프를 사용하여 여러 번 교체 살 수 있다면 http://ideone.com/ZzBem

+0

그게 아주 구체적이지만 똑똑한 해결책 :) 내 대답은보다 일반적인 해결책을 포함합니다 :) – levu

+0

'foo (foo)'는 무엇입니까? 첫 번째 foo도 대체되지만'()'안에 있지 않습니다. – levu

+0

@levu - 괄호가 올바르게 매치되어 중첩되어 있지 않다는 전제가 있습니다. 그렇지 않으면 편심한 엣지 케이스를 처리하는 것이 OP에 달려 있습니다. – Kobi

0

는이 솔루션이 작동합니다

do { 
    $string = preg_replace('/(\([^)]*)foo([^)]*\))/U', '\1boo\2', $string, -1, $count); 
}while($count != 0); 
echo $string; 
1

이를 모든 foo() 안에 찾아서으로 바꿉니다.. 제 경험으로 볼 때 preg_replace보다 빠릅니다.

while (preg_match_all('/^(.*)(\([^\)]*foo[^\)]*\))(.*)$/', $string, $pat)) { 
    $string = $pat[1] . str_replace('foo', 'boo', $pat[2]) . $pat[3]; 
} 

주 세 그룹 다음 ( ($pat[1]) 이전 문자열, foo ($pat[2])가 포함 된 ()의 문자열과 ) ($pat[3]) 뒤에있는 문자열입니다.

관련 문제