Я создал систему шаблонов, которая заменяет все переменные, начинающиеся и заканчивающиеся на «%%». Проблема в том, что preg replace иногда заменяет больше, чем нужно, вот пример:
<?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%[^%]+%/
Вот regex demo!
Проблема заключается в неправильном дизайне и не должна решаться с помощью каких-то изящных регулярных выражений. Подумайте об использовании уникальных идентификаторов для заполнителей и сопоставляйте их только из разрешенного списка имен переменных.
Такие как $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);