2015-05-21 47 views
9

最近我一直在研究(更多的是在實踐中說實話)正則表達式,我注意到他的力量。我的這個要求(link),我知道'反向引用'。我想我理解它是如何工作的,它在JavaScript中工作,而在PHP中不工作。反向引用在PHP中不起作用

例如,我有這個字符串:

[b]Text B[/b] 
[i]Text I[/i] 
[u]Text U[/u] 
[s]Text S[/s] 

,並使用以下正則表達式:

\[(b|i|u|s)\]\s*(.*?)\s*\[\/\1\] 

這種測試它regex101.com作品,同爲JavaScript,但不與PHP工作。

preg_replace(不工作)例:

echo preg_replace(
    "/\[(b|i|u|s)\]\s*(.*?)\s*\[\/\1\]/i", 
    "<$1>$2</$1>", 
    "[b]Text[/b]" 
); 

雖然這樣的工作:

echo preg_replace(
    "/\[(b|i|u|s)\]\s*(.*?)\s*\[\/(b|i|u|s)\]/i", 
    "<$1>$2</$1>", 
    "[b]Text[/b]" 
); 

我能不明白的地方,我錯了,感謝大家誰幫助我。

回答

10

這是因爲你使用雙引號的字符串,雙引號的字符串\1讀作字符(控制字符SOH =標題的開始)的八進制符號裏面,而不是作爲一個逃脫1.

因此,兩種方式:

使用單引號字符:

'/\[(b|i|u|s)\]\s*(.*?)\s*\[\/\1\]/i' 

或轉義反斜線獲得反斜槓(對於字符串,而不是爲圖案):

"/\[(b|i|u|s)\]\s*(.*?)\s*\[\/\\1\]/i" 

順便說一句,你可以寫你的模式是這樣的:

$pattern = '~\[([bius])]\s*(.*?)\s*\[/\1]~i'; 

// with oniguruma notation 
$pattern = '~\[([bius])]\s*(.*?)\s*\[/\g{1}]~i'; 

// oniguruma too but relative: 
// (the second group on the left from the current position) 
$pattern = '~\[([bius])]\s*(.*?)\s*\[/\g{-2}]~i'; 
+0

謝謝你的回答,我不認爲我做了那樣的錯誤。然而,我試圖用〜(誰不知道說實話)的模式,但不工作不是它 但它不適用於每個人,或我錯了嗎? [link](https://regex101.com/r/gV7xR5/2) –

+0

但是,你能簡單地解釋一下(如果不是混亂),''''和'〜'之間的區別嗎? –

+1

@MicheleLapolla:你可以自由選擇你想要的模式分隔符(http://php.net/manual/en/regexp.reference.delimiters.php),以避免在模式中逃避字面斜槓,'〜'是一個更好的選擇。這三種模式運行良好,您可以在這裏查看:https://eval.in/368317 –