Регулярное выражение для сопоставления открытых и закрытых пользовательских тегов - PullRequest
0 голосов
/ 19 февраля 2019

Я создаю собственный анализатор шаблонов и хочу компилировать содержимое шаблона в код 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');
    }),
]); ?>

1 Ответ

0 голосов
/ 19 февраля 2019

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

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

<?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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...