preg_replace Можно ли заменить все между двумя символами?

Я создал систему шаблонов, которая заменяет все переменные, начинающиеся и заканчивающиеся на «%%». Проблема в том, что preg replace иногда заменяет больше, чем нужно, вот пример:

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

Это выводит «100 после текста», и должно выводить «100% текста после текста». Есть ли какое-то решение этого? Это действительно плохо, потому что, если в документе есть правила CSS, используются процентные знаки, и это в конечном итоге заменяет весь документ.

1

Решение

Используйте отрицательный взгляд сзади, чтобы соответствовать всем % символы, которых нет сразу после номера.

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

Затем замените соответствующие строки пустой строкой.

DEMO

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

Выход:

100% text after text
1

Другие решения

Вы можете найти из двух % символы с этим регулярным выражением (и заменить его), если это то, что вы просите:

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

Вот regex demo!

1

Проблема заключается в неправильном дизайне и не должна решаться с помощью каких-то изящных регулярных выражений. Подумайте об использовании уникальных идентификаторов для заполнителей и сопоставляйте их только из разрешенного списка имен переменных.

Такие как $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

1
По вопросам рекламы [email protected]