First of all I want to apolagize if there is existing thread, I searched a lot, but could not find solution.
So I have preg_replace_callback function which replace specific tags in string with function.
Example:
$object = preg_replace_callback('~{FUNC\s+(.+?)}(.+?){/FUNC}~is', function($matches) use ($replace)
{
list($condition, $function, $content) = $matches;
return $function($content);
}, $object);
But when I use sub-tag inside the other tag it fails
Example:
{FUNC name_of_func}
text
text
text
{FUNC name_of_func2}text 2{/FUNC}
text
text
{/FUNC}
I know it finds the first closing tag and thats the problem, but im bad with regex, how to fix that so I can use multiple sub-tags or sub-sub-tags if thats possible?
To perform custom replacements of eventually nested structures using preg_replace_callback
an easy way consists to replace innermost parts first in a while
loop until there's nothing to replace. To do that, your pattern must forbid nested parts.
Other thing, instead of copying match arrays unnecessarily using list()
, it's better to use named captures:
$replace = [
'func1' => function ($var) { /*...*/ },
'func2' => function ($var) { /*...*/ },
//...
];
$pattern = '~{FUNC \s+ (?<funcName> \w+ )}
(?<content> [^{]*+ (?: { (?!/?FUNC\b) [^{]* )*+ )
{/FUNC}~xi';
do {
$object = preg_replace_callback($pattern, function($m) use ($replace) {
return $replace[$m['funcName']]($m['content']);
}, $object, -1, $count);
} while ($count);