多个递归模式似乎不起作用

时间:2014-08-03 22:18:39

标签: php regex templates

我有一个模板类来处理模板,所以这是从该类中获取的一行。我将提供许多细节,因为其中许多细节都与加载模板有关。

$tmpl = <<<tem
    <div id="header2">
<a rel="home" href="//localhost/index.php">
    <h1>Test Site</h1>
</a>
</div>
<nav>
    <div class="menu">
        <ul>
            <li class="base">
                <a rel="home" href="//localhost/index.php">Home</a>
            </li>
            <li><a href="//localhost/search.php">Search</a></li>
            {if(\$is_guest)}
                <li><a href="//localhost/member.php?view=register">Register</a></li>
                <li><a href="//localhost/member.php?view=login">Login</a></li>
            {/if}{else}
                <li><a href="//localhost/profile.php?uid=1">Profile</a></li>
                <li><a href="//localhost/usercp.php">My Account</a></li>
                <li><a href="//localhost/member.php?view=logout">Logout</a></li>
            {/else}
            {if(\$is_admin)}
                <li><a href="//localhost/admin">Admin</a></li>
            {/if}
            {!nav}
        </ul>
        <div class="floater"></div>
    </div>
</nav>
tem;

    $tmpl = preg_replace_callback('#{\$(.+?)}#u',array(get_class($this),'varsub'),$tmpl);
    $tmpl = preg_replace_callback("#{if\(([A-Za-z0-9\$_!]+)\)}((?:(?R)|.*?)+)\{/if\}\{else\}((?:(?R)|.*?)+)\{/else\}#ismu",array(get_class($this),'boolelsesub'), $tmpl);

出于某种原因,这个正则表达式会导致页面永远不会加载,而不是按照我的预期进行操作。 我查看了很多在线资源,但是,他们似乎都没有提到同时使用两个递归模式。

它似乎没有达到我分配给它的回调。

protected function boolelsesub($input)
{
    var_dump($input);
    $h = fopen('bah.txt', 'a');
    fwrite($h,'test');
    fclose($h);
    exit;
}

编辑:boolelsesub的内容,已被删除以便于调试。

1 个答案:

答案 0 :(得分:1)

尝试使用此模式:

$pattern = <<<'LOD'
~
{ if \( ([^)]+) \) }

( (?>[^{]+|(?R))* )

{ / if }
(?:
    { else }

    ( (?>[^{]+|(?R))* )

    { / else }
)?
~ix
LOD;

Online demo

即使您的模式适用于此编辑,由于(?:(?R)|.*?)+,结果也会效率低下。这部分效率很低,特别是因为.*?是惰性的并且可以匹配空字符串。为了解决这个问题,我用一个带有贪婪量词[^{]+

的否定字符类替换它