Рекурсивный шаблон регулярных выражений в переполнении стека

Я хотел бы использовать аннотации в стиле тегов в html-тексте для замены разделов text / html в зависимости от имен переменных с использованием PHP. Сама замена отлично работает, если не использовать вложенные теги.
Но если есть вложенные теги, заменяется только внешний.

Вот мое регулярное выражение:

\[\@if(not)?:([a-zA-Z0-9]+)(?:=(.*?))?\].*?\[\@endif:\2\]

Вы можете увидеть это регулярное выражение в действии с примером содержимого для анализа здесь:
https://regex101.com/r/rE3fL1/2

Я читал о (?R) но не могу заставить его работать.
Я пытался заменить .*? в середине с (.*?|(?R)) но это даже ничего не меняет.

Как изменить регулярное выражение, чтобы также захватывать вложенные теги?

Код: ($this->output получает доступ к тексту)

public function output($dbAccess = true) {
// only translate when dbaccess is granted
if ($dbAccess)
$this->localize();

// insert values into template
foreach ( $this->values as $key => $value ) {
$tagToReplace = "[@$key]";
$this->output = str_replace ( $tagToReplace, $value, $this->output );
}

// gather conditional content sections from output
$condis = array();
$conmatches = array ();
preg_match_all ( '/\[\@if(not)?:([a-zA-Z0-9]+)(?:=(.*?))?\].*?\[\@endif:\2\]/s', $this->output, $conmatches );
if (count($conmatches) > 0) {
$c = $conmatches[0];
//          if (count($c) > 0)
//              echo "found " . count($c[0]) . " conditional tpl statement matches!";
for ($i=0; $i<count($c); $i++) {
$text = $c[$i];
$not = $conmatches[1][$i];
$name = $conmatches[2][$i];
$value = $conmatches[3][$i];
$condis[] = new ConditionalContent($text, $not, $name, $value);
}

// substitute conditional content sections
foreach ($condis as $cc) {
// convenience and readability vars!
$varname = $cc->name();
$vals = &$this->values;
$value = $cc->value();

// if condition is bound to value of variable and not just existence
if ($value != "") {
// del if name == exists(value)
if ($cc->not() && isset($vals[$varname])) {
if ($vals[$varname] == $value) {
$this->delContent($cc->content());
}
}
// del if not exists(value) or value != name
else {
if (!isset($vals[$varname]) || $vals[$varname] != $value) {
$this->delContent($cc->content());
}
}
}
else {
if (    isset($vals[$varname]) && $cc->not() ||
!isset($vals[$varname]) && !$cc->not()) {
$this->delContent($cc->content());
}
}
}

// delete all left over if(not) and endif statements
$this->output = preg_replace('/\[@(?:if(?:not){0,1}|endif):[a-zA-Z0-9]+(=.*?)?\]/', '', $this->output);
}
//else { echo "found no conditional tpl statements"; }

return $this->output;
}

1

Решение

Задача ещё не решена.

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

Других решений пока нет …

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