2013-02-04 146 views
0

我怎麼能轉換是這樣的:替換字符出現的所有引號內的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

回答

1

這應爲單引號和雙引號做到這一點:

$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 –

1

您可以使用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如果什麼圓括號已經逃脫了?它再次逃脫了他們...... –

1

鑑於串

$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) 
1

以下說明如何使用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); 
相關問題