Регулярное выражение для сопоставления открытых и закрытых пользовательских тегов

Я разрабатываю собственный синтаксический анализатор шаблонов и хочу, чтобы шаблон компилятора содержимое в php-код с помощью синтаксиса шаблона {php xxx}.

я пытаюсь использовать

preg_replace('/{php\s+([^}]+)*}/', '<?php $1?>', '{php echo 'a' }'); можно работать с одной строкой от {php echo 'a' } до <?php echo 'a' ?>

а затем измените поддержку шаблона с помощью нескольких строк

$content = "
{php print_r([
    'foo' => 'bar',
])}
";
echo preg_replace('/{php\s+([^}]+)*}/', '<?php $1?>', $content);

теперь вопрос в том, как поддерживать функцию php в синтаксисе шаблона {php xxx}.

исходное содержимое шаблона:

{php echo yii\bootstrap\Nav::widget([
   'options' => ['class' => 'navbar-nav'],
    'items' => array_walk($menu, function($data) {
       return yii\helpers\ArrayHelper::remove($data, 'items');
    }),
]); }

целевой php-код

<?php echo yii\bootstrap\Nav::widget([
   'options' => ['class' => 'navbar-nav'],
    'items' => array_walk($menu, function($data) {
       return yii\helpers\ArrayHelper::remove($data, 'items');
    }),
]); ?>

вам нужно регулярное выражение для {php some_text} ?\

melvin 19.02.2019 05:34

Учтите, что {php echo "text with {$braces['key']}";} Regex — неправильный инструмент для разбора сложных структур.

Quasimodo's clone 19.02.2019 05:43

Последний } всегда закрывается? Если да, то regex101.com/r/0ukTba/1, я думаю, подходит. Если нет, вам нужно предоставить больше примеров и более подробное объяснение.

user3783243 19.02.2019 05:46

Это может даже произойти что-то вроде {php $end='}'; $start = '{'; echo "$start something $end";}. Тогда концепция вложения фигурных скобок с использованием рекурсивных выражений также будет нарушена. Вам нужно будет принять во внимание все случаи, такие как строки (одиночные/двойные кавычки, heredoc, nowdoc...) и другие случаи, где может возникнуть закрывающая фигурная скобка.

Quasimodo's clone 19.02.2019 05:49

Вы разрабатываете свой собственный язык шаблонов или полагаетесь на данный?

Quasimodo's clone 19.02.2019 05:56

@ user3783243 у меня это не работает. я обновил вопрос

user10666794 19.02.2019 06:31

Вы непонятливы и не отвечаете ни на один вопрос в комментариях.

Quasimodo's clone 19.02.2019 07:17
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
7
35
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как я уже упоминал в комментариях, регулярное выражение — неправильный инструмент для разбора структурированного кода.

Однако, если вы можете гарантировать, что фигурные скобки всегда встречаются попарно и без экранирования, вы можете использовать рекурсивное регулярное выражение:

<?php
declare (strict_types=1);

$subject = <<<'EOS'
<div>{php echo yii\bootstrap\Nav::widget([
   'options' => ['class' => 'navbar-nav'],
    'items' => array_walk($menu, function($data)
    {
      if (true)
      { 
        $x = "{}sdf{ {{}{}}{} }";
      }
      return yii\helpers\ArrayHelper::remove($data, 'items');
    }),
]); }</div>

<div>{php echo yii\bootstrap\Nav::widget([
   'options' => ['class' => 'navbar-nav'],
    'items' => array_walk($menu, function($data)
    {
      if (true)
      { 
        $x = "{}sdf{ {{}{}}{} }";
      }
      return yii\helpers\ArrayHelper::remove($data, 'items');
    }),
]); }</div>
EOS;

var_dump(preg_replace( '~{php(\s([^{}]|{([^{}]*(?2))*})*)}~suU', '<?php\1?>', $subject));

Протестируйте онлайн: https://regex101.com/r/hGqVeq/2

это работа для меня. Большое спасибо за описание и пример.

user10666794 19.02.2019 09:47

Другие вопросы по теме