我正在尝试从laravel复制刀片,以便学习,但我遇到了一个问题
当使用preg_replace创建解析器时,除了与括号的特定交互之外,一切都很正常;')‘
ThisIsGonnaBeParsed.php
@if ($user->loggedIn() || true)
<p>welcome {{$user->name}}</p>
@endif
@if (true)
<p>hello</p>
@endif
PATTERN =>替换
'/{{(.+?)}}/s' => '<?php echo \1; ?>',
'/@if(\s|)\((.+?)\)/s' => '<?php if (\2): ?>',
'/@endif/' => '<?php endif; ?>'
正如您所看到的,除了存储在括号之间的内容之外,所有内容都被替换。但结果中有些地方出了问题。
完整结果
<?php if ($user->loggedIn(): ?> || true)
<p>welcome <?php echo $user->name; ?></p>
<?php endif; ?>
<?php if (true): ?>
<p>hello</p>
<?php endif; ?>
有错误的部分
<?php if ($user->loggedIn(): ?> || true)
正如您所看到的,只要它遇到),它就会将从这一点开始的所有内容都抛到字符串的后面
我真正想要的结果
<?php if ($user->loggedIn() || true): ?>
我试着用谷歌搜索,但没有找到任何结果
发布于 2019-04-30 07:34:24
您的问题是,您的内部括号匹配.+?
并不贪婪,所以它停在第一个)
,也就是$user->loggedIn()
末尾的那个。您可以通过使用贪婪匹配来解决这个问题,但是您还需要删除s
修饰符,该修饰符允许.
匹配换行符,否则将导致它与if (true)
末尾的)
匹配。这将意味着您的if
条件不能超过换行符,但如果这是可以的,那么这应该是可行的:
$replacements = array(
'/{{(.+?)}}/' => '<?php echo $1; ?>',
'/@if\s*\((.+)\)/' => '<?php if ($1): ?>',
'/@endif/' => '<?php endif; ?>'
);
echo preg_replace(array_keys($replacements), $replacements, $code);
输出:
<?php if ($user->loggedIn() || true): ?>
<p>welcome <?php echo $user->name; ?></p>
<?php endif; ?>
<?php if (true): ?>
<p>hello</p>
<?php endif; ?>
https://stackoverflow.com/questions/55911962
复制相似问题