我正在用PHP为我自己的个人项目编写一个模板编译器,遇到了一个问题,如果条件以)
结尾,则@if
指令无法正确获取指令的内容。
private function handleIf(string $page): string
{
return preg_replace('/@if ?\( ?(.*?) ?\)(.*?)@endif/is', '<?php if ($1) { ?> $2 <?php } ?>', $page);
}
// the directive...
// @if(!empty($title))
// should result in
<?php !empty($title) { ?>
// but is instead rendered as
<?php !empty($title { ?>
// which obviously no worky
我该如何调整我的正则表达式来正确地匹配它?它必须是全局的和多行的,因为它是模板的一部分。我可以使用其他方法来提取指令吗?
2条答案
按热度按时间raogr8fs1#
对于给定的示例,您可以使用递归模式来匹配
@if
后面的平衡括号。请注意,您正在将php代码与正则表达式进行匹配,这可能会给予意想不到的副作用。
@if\h*
匹配@if
,后跟可选空格(
捕获组1\(
匹配(
(
捕获组2(?:[^()]++|(?1))*
重复匹配除(
或)
以外的任何字符,或重复第一个子模式)
关闭组2\)
匹配)
)
关闭组1\s*(.*?)\s*
捕获组3,在可选的空白字符之间匹配尽可能少的任何字符@endif\b
匹配@endif
后跟一个字边界Regex demo|Php demo
输出
如果您不想在中间交叉另一个
@if(
:Regex demo
pqwbnv8z2#
可以看到这个代码
输入文本
输出
完整代码:
可以通过此链接https://rextester.com/DSN63422运行