【问题标题】:Multiple Recursion Patterns don't seem to work多重递归模式似乎不起作用
【发布时间】:2014-08-03 22:18:38
【问题描述】:

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

$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 的内容,为了便于调试,已对其进行了精简。

【问题讨论】:

  • 您能提供$tmpl 的内容吗?看起来你在回调函数中使用了错误的语法。
  • 并提供boolelsesub功能码。

标签: php regex templates


【解决方案1】:

试试这个模式:

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

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

{ / if }
(?:
    { else }

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

    { / else }
)?
~ix
LOD;

Online demo

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

【讨论】:

  • 反斜杠字符用于转义 $ 字符,否则 PHP 会认为我正在尝试在其中插入一个变量,因为它是双引号。所以,这不应该导致问题,当我使用 (.*?) 而不是递归模式时它工作得非常好。
  • @Azareal: 什么返回 preg_last_error() ?我认为已经达到回溯限制。
猜你喜欢
  • 1970-01-01
  • 2019-06-14
  • 1970-01-01
  • 2011-01-15
  • 2014-01-13
  • 2014-08-05
  • 2018-11-27
  • 2019-11-01
  • 1970-01-01
相关资源
最近更新 更多