Я хотел бы использовать аннотации в стиле тегов в 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;
}
Задача ещё не решена.
Других решений пока нет …