我正在设计一个自定义模板解析器,并且想要编译模板
内容通过{php xxx}
模板语法转换为php代码。
我尝试使用
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 xxx}
模板语法支持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代码
<?php echo yii\bootstrap\Nav::widget([
'options' => ['class' => 'navbar-nav'],
'items' => array_walk($menu, function($data) {
return yii\helpers\ArrayHelper::remove($data, 'items');
}),
]); ?>
答案 0 :(得分:0)
正如我在评论中已经提到的,正则表达式是解析结构化代码的错误工具。
但是,只要您可以确保括号总是成对出现且未转义,则可以使用递归正则表达式:
<?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));