Задать вопрос
@artmirarmi

Как сделать замену по регулярному выражению?

Здравствуйте. Я пытаюсь сделать на php свой шаблонизатор, сейчас я делаю цыклы. Вот пример цикла:
[[ @times(5) ]]
  <p>{{ $message }}</p>
[[ @times(#end) ]]


Код выше просто выводит {{ $message }} пять раз. И все хорошо, но если использовать вложенные циклы, например:
[[ @times(5) ]]
  [[ @times(2) ]]
    <p>{{ $message }}</p>
  [[ @times(#end) ]]
[[ @times(#end) ]]

то результат будет таким:
[[ @times(5) ]]
    Hello world!
    Hello world!
[[ @times(#end) ]]

Как сделать чтобы внутренний цикл срабатывал нормально?

Я использую следующий код обработки таких конструкций:
public static function dirs($code, $data) {
    $pattern = '/\[\[\s*@([^\(]+)\(([^\)]+)\)\s*\]\]([^\[]+)\[\[\s*@([^\(]+)\(#end\)\s*\]\]/i';
    return preg_replace_callback($pattern, function($value) use($data) {
      if($value[1] == 'times') return str_repeat($value[3], $value[2]); // $value[3] - строка <p>{{ $message }}</p>, $value[2] = 5;
    }, $expression);
  }

Тут я просто ищу все конструкии такого вида [[ @times(n) ]] Some text... [[ @times(#end) ]], и вывожу их n раз
Как сделать чтобы внутренний цикл срабатывал нормально?

UPD: Переменная $message равна "Hello world!"
  • Вопрос задан
  • 134 просмотра
Подписаться 1 Средний Комментировать
Пригласить эксперта
Ответы на вопрос 1
SilenceOfWinter
@SilenceOfWinter Куратор тега PHP
та еще зажигалка...
Рекурсивный вывоз использовать что-то вроде этого:
public static function dirs($code, $data) {
    $pattern = '/\[\[\s*@([^\(]+)\(([^\)]+)\)\s*\]\]([^\[]+)\[\[\s*@([^\(]+)\(#end\)\s*\]\]/i';
    return preg_replace_callback($pattern, function($value) use($data) {
      if($value[1] == 'times') {
           if (!empty($value[3])) {
                  $value[3] = self::dirs($value[3], $data);
           }
           return str_repeat($value[3], $value[2]);
}
    }, $expression);
  }
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы