2012-06-07 88 views
5

对于PHP中的自定义脚本解析器,我想用多行字符串替换包含双引号和单引号的单词。 但是,只有以外的文字才能被替换。如何替换双引号和单引号以外的单词

Many apples are falling from the trees.  
"There's another apple over there!"  
'Seedling apples are an example of "extreme heterozygotes".' 

例如,我想用'pear'替换'apple',但只是在引号之外。所以在这种情况下,只有'苹果'在'许多苹果从树上掉下来'才会成为攻击目标。

以上将给出以下的输出:

Many pears are falling from the trees.  
"There's another apple over there!"  
'Seedling apples are an example of "extreme heterozygotes".' 

我怎样才能做到这一点?

+0

你可以发布你的PHP脚本解析这样我们可以建议修改。 –

回答

6

此功能的伎俩:

function str_replace_outside_quotes($replace,$with,$string){ 
    $result = ""; 
    $outside = preg_split('/("[^"]*"|\'[^\']*\')/',$string,-1,PREG_SPLIT_DELIM_CAPTURE); 
    while ($outside) 
     $result .= str_replace($replace,$with,array_shift($outside)).array_shift($outside); 
    return $result; 
} 

它是如何工作它拆分通过引用的字符串,但包括这些引用的字符串,这给你交的非上市,报价,无报价,报价等字符串在一个数组中(一些非引号字符串可能为空)。然后在替换单词和不替换之间交替,因此只有非引号字符串被替换。

你的榜样

$text = "Many apples are falling from the trees.  
     \"There's another apple over there!\"  
     'Seedling apples are an example of \"extreme heterozygotes\".'"; 
$replace = "apples"; 
$with = "pears"; 
echo str_replace_outside_quotes($replace,$with,$text); 

输出

Many pears are falling from the trees.  
"There's another apple over there!"  
'Seedling apples are an example of "extreme heterozygotes".' 
+0

工作正常,非常感谢! – Nick

+0

我无法得到我的[第一个答案](http://stackoverflow.com/revisions/10929115/1)中使用的正则表达式可靠地工作,所以我创建了这个函数,而它始终工作。 – Timm

+0

我测试了你的脚本,发现了一个bug。如果你的字符串中有\'或\“这个转义字符,它会很快关闭,导致不可预知的结果。这个正则表达式修复了/('(?:[^ \\\\'] + | \\\\(\\ \\\\\\)*)*'| \。 “(?:[^ \\\\\”。] + | \\\\(\\\\\\\\)*)* \“) /。它不漂亮,但它的工作原理。必须有一个更优雅的解决方案,但我现在不能浪费更多时间。 –

0

只是想一想:通过删除引用部分来创建一个临时字符串,替换您需要的部分,然后添加您删除的引用部分。

+0

如何将原始位置的引用部分重新添加到原始字符串中? – Nick

1

我想出了这一点:

function replaceOutsideDoubleQuotes($search, $replace, $string) { 
    $out = ''; 
    $a = explode('"', $string); 
    for ($i = 0; $i < count($a); $i++) { 
     if ($i % 2) $out .= $a[$i] . '"'; 
     else $out .= str_replace($search, $replace, $a[$i]) . '"'; 
    } 
    return substr($out, 0, -1); 
} 

的逻辑是:你用双引号爆炸字符串,所以返回的字符串数组的元素表示引号外的文字,并甚至一些代表双引号内的文本。

因此,您可以通过连接原始零件和替换零件来构建输出,好吗?

工作示例这里:http://codepad.org/rsjvCE8s

+0

谢谢,但它只适用于双引号......我需要的东西只能取代双引号和单引号之外:) – Nick

0

可以使用了preg_replace,使用正则表达式通过增加另一个正则表达式中更换里面的话“”

$search = array('/(?!".*)apple(?=.*")/i'); 
$replace = array('pear'); 
$string = '"There\'s another apple over there!" Seedling apples are an example of "extreme heterozygotes".'; 

$string = preg_replace($search, $replace, $string); 

您可以添加更多的可能搜索的对象$ search和$ replace中的另一个替换字符串

此RegEx使用向前查找和向后查找来查找搜索的字符串是否位于“”

+0

对不起,我只注意到我看错了这个问题 - 相反的问题。我会改变它...... – Katai

+0

它似乎是做了与问题相反的问题,在**引号内替换文本**,而不是在外面。 –