2016-09-23 78 views
1

我有一個由重複單詞組成的字符串。我想替換位於'L3'和'L4'之間的子字符串'OK'。下面你可以找到我的代碼:如果我使用圖案的preg_match如何用preg_replace幫助替換子字符串

$search = "/(?<=L3).*(OK).*(?=L4)/"; 
$replace = "REPLACEMENT"; 
$subject = "'L1' => ('Vanessa', 'Prague', 'OK'), 'L2' => ('Alex', 'Paris', 'OK'), 'L3' => ('Paul', 'Paris', 'OK'), 'L4' => ('John', 'Madrid', 'OK')"; 
$str = preg_replace($search, $replace, $str); 

,找到一個正確的字符串(第三「OK」)。但是,當我將該模式應用於preg_replace時,它會替換與完整模式匹配的子字符串,而不是括號內的子模式。

所以,你可以給我一個建議,我應該改變我的代碼?我知道有很多關於正則表達式的類似問題,但據我所知我的模式是正確的,我只是與preg_replace函數混淆

回答

1

確實,您的正則表達式匹配前面的字符串中的某個位置L3然後包含最後的OK子字符串,除了換行符號之外的0+字符,然後匹配任何0+字符,然後匹配L4。見your regex demo

一種可能的解決方案是使用周圍子模式2個捕獲組之前和OK後,並且在替換模式使用反向引用:

$search = "/(L3.*?)OK(.*?L4)/"; 
$replace = "REPLACEMENT"; 
$subject = "'L1' => ('Vanessa', 'Prague', 'OK'), 'L2' => ('Alex', 'Paris', 'OK'), 'L3' => ('Paul', 'Paris', 'OK'), 'L4' => ('John', 'Madrid', 'OK')"; 
$str = preg_replace($search, '$1'.$replace.'$2', $subject); 
echo $str; // => 'L1' => ('Vanessa', 'Prague', 'OK'), 'L2' => ('Alex', 'Paris', 'OK'), 'L3' => ('Paul', 'Paris', 'REPLACEMENT'), 'L4' => ('John', 'Madrid', 'OK') 

參見PHP demo

如果不可能有任何L3.5L3L4之間,(L3.*?)OK(.*?L4)模式可以安全使用。它將匹配並捕獲L3,然後將0+字符以外的第一個OK,然後匹配OK,然後匹配並捕獲0+個字符,直到第一個L4

如果不能有任何L4,使用(?:(?!L4).)*回火貪婪令牌匹配比沒有啓動的L4序列斷行符號以外的任何符號:

'~(L3(?:(?!L4).)*)OK~' 

regex demo

注意 :如果您想使正則表達式更安全,請在模式內添加約L#附近的'