我有一个由重复的单词组成的字符串。我想替换位于'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函数混淆
答案 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.5
和L3
之间不能有L4
,(L3.*?)OK(.*?L4)
模式可以安全使用。它将匹配并捕获L3
,然后捕获除第一个OK
之外的换行符以外的0个字符,然后匹配OK
,然后匹配并捕获0 +字符到第一个L4
。
如果没有L4
,请使用(?:(?!L4).)*
淬火贪婪令牌,以匹配未启动L4
序列的换行符号以外的任何符号:
'~(L3(?:(?!L4).)*)OK~'
请参阅regex demo
注意:如果您想让regexp更安全,请在模式中的'
附近添加L#
。