preg_replace是否可以替换两个符号之间的所有内容


preg_replace Is it possible to replace everything in between two symbols?

我创建了一个模板系统,用于替换以"%%"开头和结尾的所有变量。问题是preg替换有时会替换超出应有的数量,这里有一个例子:

<?php
    $str  = "100% text %everythingheregone% after text";
    $repl = "test";
    $patt = "/'%([^']]+)'%/"; 
    $res  = preg_replace($patt, "", $str);
    echo $res;
?>

这将输出"文本之后的100",并且应该输出"文本后的100%文本"。有什么解决办法吗?这真的很糟糕,因为如果文档中有CSS规则,就会使用百分比符号,最终会替换所有文档。

使用负查找将后面不存在的所有%符号与数字匹配。

(?<!'d)%([^%]*)'%

然后用空字符串替换匹配的字符串。

演示

$str  = "100% text %everythingheregone% after text";
$repl = "test";
$patt = "/(?<!'d)%([^%]*)'%'s*/"; 
$res  = preg_replace($patt, "", $str);
echo $res;

输出:

100% text after text

您可以用这个正则表达式找到最后一个出现的两个%符号(并替换掉),如果这就是您想要的:

/.*'K%[^%]+%/

这是一个正则表达式演示!

这个问题是一个错误的设计,不应该用一些漂亮的正则表达式来解决。考虑为占位符使用唯一标识符,并且只与允许的变量名列表匹配。

$str = "100% text {%_content_%}";

并使用str_replace()替换

$res = str_replace("{%_content_%}", "test", $str);

或strtr()用于多次替换:

$replace_map = array(
"{%_content_%}" => "test",
"{%_foo_%}" => "bar",
);
$res = strtr($str, $replace_map);

只是一个针对核心问题的想法。


在此之前更换%containing_word_characters%

$res = preg_replace('~%'w+%~', "test", $str);

在regex101 上测试