2011-01-10 303 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`之前有空吗?还是应该插入? – 2011-01-10 03:29:40

+0

我可以管理这个空间。使用urldecode唯一的问题是,这是一个SQL查询,我只想要urldecode双引号,只有当他们在这种模式。 – S16 2011-01-10 03:35:59

回答

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

说明:$1是反向引用,它引用在第一() -section在正则表达式在这种情况下,((?:[^%]|%[^2]|%2[^2])*)。而[^%](...|...|...)之后的变化阻止了%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 2011-01-10 03:37:03

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; 
?>