【问题标题】:PHP nested if conditionsPHP嵌套if条件
【发布时间】:2013-03-29 13:05:57
【问题描述】:

我正在使用模板系统。在这个模板系统中,我对 if-else 条件使用如下所示的结构;

<if condition="'$condition' != 1">
    <div>true source</div>
</if>

比我用以下模式分隔表达式;

$pattern_case = '<if condition="(.*?)">(.*?)</if>';
preg_match("#$pattern_case#si",$string,$case)

但在某些情况下,if-else 进程可以在另一个中使用(嵌套?- recusirve?)例如;

<if condition="'$condition1' != 1">
    <div>condition 1 text</div>
    <if condition="'$condition2' == 2 ">
        <div>condition 2 text</div>
    </if>
    condition 1 text more
</if>

在这种情况下,模式给出以下结果。

<if condition="'$condition1' != 1">
    <div>condition 1 text</div>
    <if condition="'$condition2' == 2 ">
        <div>condition 2 text</div>
    </if>

(所以没有这个)

    condition 1 text more
</if>

如果不使用 domdocument,如何使用 regex 解决该问题?

【问题讨论】:

    标签: php regex nested


    【解决方案1】:

    你可以。 “按照设计,正则表达式无法处理递归。”是的,但 PCRE 提供了比严格的正则表达式语言更多的功能。这就是为什么“正则表达式”一词在许多语言中不准确地指代“正则表达式”的原因。

    这样做的方法:

    $subject = <<<'LOD'
    <if condition="'$condition1' != 1">
    <div>condition 1 text</div>
    <if condition="'$condition2' == 2 ">
    <div>condition 2 text</div>
    </if>
    condition 1 text more
    </if>
    LOD;
    $pattern = '~<if condition="(?<condition>[^"]+)">(?<content>(?:.*?(?R)?)+?)</if>~s';
    preg_match_all( $pattern, $subject, $matches );
    print_r($matches); // see your html source
    

    此代码与您的嵌套结构匹配。 现在,坏消息是:您无法使用单一模式从其他深度捕获“条件”和“内容”! 一种方法是创建一个递归函数,在“内容”上重试模式并在没有更多嵌套的“if”时停止。
    对于替换,您还可以构建一个描述最内层“if”标签的模式(一种禁止其他嵌套“if”的模式)并将其应用到do..while 循环中。

    请记住,这种方法具有很高的复杂性(在算法意义上),更好的方法是使用 DOM。

    【讨论】:

      【解决方案2】:

      你不能。按照设计,正则表达式无法处理递归。

      有关更多信息,您可能想在此处阅读第一个答案:Can regular expressions be used to match nested patterns?

      是的,我知道一些特殊的“正则表达式”确实允许递归。但是,在大多数情况下,这意味着您正在做一些可怕的事情。

      【讨论】:

        猜你喜欢
        • 2017-11-08
        • 1970-01-01
        • 2010-12-17
        • 2020-02-25
        • 2023-03-08
        • 2016-08-28
        • 2012-02-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多