Если вам нужно сделать что-то более сложное с содержимым, например, обработать содержимое или переменные, то вы можете использовать рекурсивное регулярное выражение, используя оператор (? R).
$data = "{{abcde{{fg{{hi}}jk}}lm}}";
$regexp = "#\{\{((?:[^(\{\{)(\}\})]+|(?R))+)\}\}#";
$count = 0;
function revMatch($matches) {
global $regexp, $count;
if (is_array($matches)) {
// Match detected, process for nested components
$subData = preg_replace_callback($regexp, 'revMatch', $matches[1]);
} else {
// No match, leave text alone
$subData = $matches;
}
// This numbers each match, to demonstrate call order
return "(" . $count++ . ":<" . $subData . ">)";
}
echo preg_replace_callback($regexp, 'revMatch', $data);
Это преобразует: {{abcde{{fg{{hi}}jk}}lm}}
в (2:<abcde(1:<fg(0:<hi>)jk>)lm>)
Немного пояснений по регулярному выражению: #\{\{((?:[^(\{\{)(\}\})]+|(?R))+)\}\}#
Двойные скобки спереди и сзади соответствуют любому целевому компоненту, содержимое скобок должно быть одним или несколькими из двух определенных параметров:
строка без двойных скобок [^(\{\{)(\}\})]+
все регулярное выражение повторяется. Скобка (?:)
- это группа без захвата.
NB. #s
- это разделители шаблонов, я думал, что дополнительные косые черты еще больше уменьшат читабельность.