我创建了一个模板系统,用于替换以"%%"开头和结尾的所有变量。问题是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 上测试