0

我正在使用模板系统。在这个模板系统中,我对 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 解决该问题?

4

2 回答 2

1

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

有关更多信息,您可能想在此处阅读第一个答案:可以使用正则表达式匹配嵌套模式吗?

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

于 2013-04-07T12:26:42.697 回答
0

你可以。“按照设计,正则表达式无法处理递归。” 是的,但 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。

于 2013-04-08T03:48:43.777 回答