PHP: preg_replace 括号交互问题 ')'

PHP: preg_replace problem with bracket interaction ')'

我正在尝试从 laravel 复制 blade 以便学习,但我遇到了问题

当使用 preg_replace 创建解析器时,除了与括号的特定交互外,一切都很顺利; ')'

ThisIsGonnaBeParsed.php

@if ($user->loggedIn() || true)

    <p>welcome {{$user->name}}</p>

@endif

@if (true)

    <p>hello</p>

@endif

模式 => 替换

        '/{{(.+?)}}/s'              => '<?php echo ; ?>',
        '/@if(\s|)\((.+?)\)/s'      => '<?php if (): ?>',
        '/@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): ?> 

我试过谷歌搜索,但找不到任何结果

你的问题是你的括号内匹配 .+? 不是贪婪的,所以它在第一个 ) 处停止,也就是 $user->loggedIn() 末尾的那个。您可以通过使用贪婪匹配来解决该问题,但您还需要删除允许 . 匹配换行符的 s 修饰符,否则会导致它匹配 ) if (true) 结束。这意味着您的 if 条件不能超过换行符,但如果没问题,那么这应该有效:

$replacements = array(
        '/{{(.+?)}}/'              => '<?php echo ; ?>',
        '/@if\s*\((.+)\)/'         => '<?php if (): ?>',
        '/@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; ?>

Demo on 3v4l.org