如何在preg_replace的帮助下替换子字符串

时间:2016-09-23 11:17:23

标签: php regex

我有一个由重复的单词组成的字符串。我想替换位于'L3'和'L4'之间的子字符串'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, $replace, $str);

如果我将该模式与preg_match一起使用,它会找到一个正确的子串(第三个'OK')。但是,当我将该模式应用于preg_replace时,它会替换匹配完整模式的子字符串,而不是括号子模式。

那么请你在我的代码中给我一个建议:我知道关于正则表达式有很多类似的问题,但据我所知,我的模式是正确的,我只是与preg_replace函数混淆

1 个答案:

答案 0 :(得分:2)

确实,你的正则表达式匹配前面带有L3的字符串中的一个地方,然后包含除了换行符号之后的0+字符之后的最后OK子字符串,然后匹配任何0+字符到L4后跟的地方。请参阅your regex demo

一种可能的解决方案是在OK之前和之后的子模式周围使用2个捕获组,并在替换模式中使用反向引用:

$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.5L3之间不能有L4(L3.*?)OK(.*?L4)模式可以安全使用。它将匹配并捕获L3,然后捕获除第一个OK之外的换行符以外的0个字符,然后匹配OK,然后匹配并捕获0 +字符到第一个L4

如果没有L4,请使用(?:(?!L4).)*淬火贪婪令牌,以匹配未启动L4序列的换行符号以外的任何符号:

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

请参阅regex demo

注意:如果您想让regexp更安全,请在模式中的'附近添加L#