PHP: проблема preg_replace с взаимодействием скобок ')' - PullRequest
0 голосов
/ 30 апреля 2019

я пытаюсь повторить лезвие из 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): ?> 

Я пробовал поискать в Google, но я не смог найти никаких результатов

1 Ответ

1 голос
/ 30 апреля 2019

Ваша проблема в том, что ваши внутренние скобки, совпадающие с .+?, не являются жадными, поэтому они останавливаются на первом ), который находится в конце $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; ?>

Демонстрация на 3v4l.org

...