2011-01-10 3 views
3

정규 표현식은 절대적으로 약점이며이 점은 완전히 저음이됩니다. 나는 상당히 기본적인 검색 기능을 구축, 그리고 난 다음 패턴에 따라 내 사용자의 입력을 변경 할 수 있어야합니다 :preg_replace를 사용하여 PHP의 모든 항목 바꾸기

제목 :

%22first set%22 %22second set%22-drupal -wordpress 

원하는 출력 :

+"first set" +"second set" -drupal -wordpress 

내가 원하는 나는 내가 지금까지 가지고있는 해결책을 최소한 게시하는 것을 선호하지만, 나는이 문제에 대해 많은 도움을 줄 수있다.

도움을 주시면 감사하겠습니다. 고맙습니다.

+1

데이터가 URL 인코딩 된 것으로 보입니다. [urldecode] (http://php.net/manual/en/function.urldecode.php)를 적용하면 "첫 번째 세트" "두 번째 세트"-drupal-wordpress'를 얻을 수 있습니다. '-drupal' 이전에 실제로 공간이 있습니까? 아니면 이것을 삽입해야합니까? –

+0

공간을 관리 할 수 ​​있습니다. urldecode를 사용하는 유일한 문제는 SQL 쿼리에서이 문제가 발생한다는 것입니다.이 패턴을 사용하는 경우에만 큰 따옴표를 urldecode하고 싶습니다. – S16

답변

1
preg_replace('/%22((?:[^%]|%[^2]|%2[^2])*)%22/', '+"$1"', $str); 

설명 : $1이 경우, ((?:[^%]|%[^2]|%2[^2])*)에서, 일반 식에 제 () -section를 참조 역 참조한다. 그리고 [^%]과 번갈아 (...|...|...)은 그 사이에 %22이 탐욕으로 인해 일치하지 못하게합니다. http://en.wikipedia.org/wiki/Regular_expression#Lazy_quantification을 참조하십시오.

내가 일치하는 블록 주석의 JavaCC에 예 ( /* */)에서 그 기술을 발견, 나는 다른 웹 페이지를 설명 찾을 수 없습니다, 그래서 여기에 깨끗한 예입니다 : 더와 12345 12345........12345 사이에 텍스트 블록과 일치하지 않으려면 사이의 12345 : /12345([^1]|1[^2]|12[^3]|123[^4]|1234[^5])*12345/

+1

당신이 흔들립니다. 고맙습니다. 솔루션에 대한 설명을 드릴 수 있습니까? – S16

+0

'$ 1'은 정규 표현식에서'((?) [^ %] | % [^ 2] | % 2 [^ 2] '의 첫 번째'()'섹션을 참조하는 역 참조입니다.) *)'. 그리고'[^ %]'는 그 사이의 % 22가 일치하지 못하도록합니다 : 탐욕스러운 일치를 막고, 탐욕은 http://en.wikipedia.org/wiki/Regular_expression#Lazy_quantification에 설명되어 있으며, [[^ %]' 방법은 http : // shinkirou에 설명되어 있습니다.org/blog/2010/12/tricky-regular-expression-problems/(JavaCC 예제에서 처음 볼 수있다.) –

+0

@SHiNKiROU 답변에 제공된 코드에 대한 설명은 ** 답변이 아닌 ** itsef ** 답변에 달려있다. 많은 사람들이 그것을 놓칠 수도 있습니다. 나는 왜 당신이 자신의 대답을 편집하지 않았고, 설명을 요구 받았을 때, 그리고 작은 의견을 대신 사용했는지 궁금합니다. – trejder

2

데이터가 URL 인코딩 된 것으로 보입니다. 당신이 urldecode을 적용하면, 당신은

"first set" "second set" -drupal -wordpress 

를 얻을 것이다 (나는 당신이 -drupal 앞에 공백이 가정).

이제 +을 추가해야합니다. 다시 말하지만, 난 당신이 -을하지 않아도 모든 단어 앞에 사람들을 추가 할 수 있다고 가정하고이되지 내부 따옴표 있습니다

$str = '"first set" "second set" -drupal -wordpress foo'; 
echo preg_replace('#(|^)(?!(?:\w+"|-|))#','\1+', $str)); 
// prints +"first set" +"second set" -drupal -wordpress +foo 

업데이트 : 당신이 urldecode을 사용할 수없는 경우, 당신은 단지 str_replace를 사용할 수 교체 %22"입니다.

1

이게 당신이 찾고 있는게 있나요?

<?php 
    $input = "%22first set%22 %22second set%22-drupal -wordpress"; 
    $res = preg_replace("/\%22(.+?)\%22/","+\"(\\1)\" ", $input); 
    print $res; 
?> 
+0

설명 : \ % 22이 (가) "% 22"과 일치합니다. 여기서 핵심은 (. +?) 부분입니다.이 부분은 % 22 사이의 가장 짧은 (즉, "ungreedy") 일치를 찾습니다. 두 번째 부분에서 \ 1은 (. +?)에서 일치하는 값을 나타냅니다. – phooji

관련 문제