替换字符出现的所有引号内的PHP

问题描述:

我怎么能转换是这样的:替换字符出现的所有引号内的PHP

"hi (text here) and (other text)" come (again) 

要这样:

"hi \(text here\) and \(other text\)" come (again) 

基本上,我想逃离“只”是括号里面的引号。

编辑

我对新的正则表达式,因此,我尝试这样做:

$params = preg_replace('/(\'[^\(]*)[\(]+/', '$1\\\($2', $string); 

但这只会逃避的第一次出现(

EDIT 2。

也许我应该提一下,我的字符串可能有这些括号al随时可以逃脱,在这种情况下,我不想再逃脱他们。顺便说一句,我需要它适用于双引号和单引号,但我认为只要我有其中一个例子的工作示例,我就可以做到这一点。

+2

[你有什么尝试?](http://www.whathaveyoutried.com/)请参阅[问问建议](http://stackoverflow.com/questions/ask-advice),请。 –

+0

我想我不明白你想添加逃逸到第一个字符串? –

+1

没有他想要逃避是引号内 – vodich

这应为单引号和双引号做到这一点:

$str = '"hi \(text here)" and (other text) come \'(again)\''; 

$str = preg_replace_callback('`("|\').*?\1`', function ($matches) { 
    return preg_replace('`(?<!\\\)[()]`', '\\\$0', $matches[0]); 
}, $str); 

echo $str; 

输出

"hi \(text here\)" and (other text) come '\(again\)' 

这是PHP> = 5.3。如果您的版本较低(> = 5),则必须使用单独的函数替换回调中的匿名函数。

+0

如果什么括号已经逃走? –

+0

@但是如果你不想要你可能不得不更新你的问题 – flec

+0

好的,我更新了我的问题,对不起= S –

您可以使用preg_replace_callback这个;

// outputs: hi \(text here\) and \(other text\) come (again) 
print preg_replace_callback('~"(.*?)"~', function($m) { 
    return '"'. preg_replace('~([\(\)])~', '\\\$1', $m[1]) .'"'; 
}, '"hi (text here) and (other text)" come (again)'); 

那么已经逃过的字符串呢?

// outputs: hi \(text here\) and \(other text\) come (again) 
print preg_replace_callback('~"(.*?)"~', function($m) { 
    return '"'. preg_replace('~(?:\\\?)([\(\)])~', '\\\$1', $m[1]) .'"'; 
}, '"hi \(text here\) and (other text)" come (again)'); 
+0

你的输出错过了引号,因为你只返回被替换的子匹配。 – flec

+0

好吧,我知道了。 –

+0

@qeremy如果什么圆括号已经逃脱了?它再次逃脱了他们...... –

鉴于串

$str = '"hi (text here) and (other text)" come (again) "maybe (to)morrow?" (yes)'; 

迭代方法

for ($i=$q=0,$res='' ; $i<strlen($str) ; $i++) { 
    if ($str[$i] == '"') $q ^= 1; 
    elseif ($q && ($str[$i]=='(' || $str[$i]==')')) $res .= '\\'; 
    $res .= $str[$i]; 
} 

echo "$res\n"; 

但如果你是递归的粉丝

function rec($i, $n, $q) { 
    global $str; 
    if ($i >= $n) return ''; 
    $c = $str[$i]; 
    if ($c == '"') $q ^= 1; 
    elseif ($q && ($c == '(' || $c == ')')) $c = '\\' . $c; 
    return $c . rec($i+1, $n, $q); 
} 

echo rec(0, strlen($str), 0) . "\n"; 

结果:

"hi \(text here\) and \(other text\)" come (again) "maybe \(to\)morrow?" (yes) 

以下说明如何使用preg_replace_callback()函数执行此操作。

$str = '"hi (text here) and (other text)" come (again)'; 
$escaped = preg_replace_callback('~(["\']).*?\1~','normalizeParens',$str); 
// my original suggestion was '~(?<=").*?(?=")~' and I had to change it 
// due to your 2nd edit in your question. But there's still a chance that 
// both single and double quotes might exist in your string. 

function normalizeParens($m) { 
    return preg_replace('~(?<!\\\)[()]~','\\\$0',$m[0]); 
    // replace parens without preceding backshashes 
} 
var_dump($str); 
var_dump($escaped);