2013-04-07 2 views
0

Я использую систему шаблонов. В этой системе шаблонов я использую структуру, показанную ниже для условий if-else;PHP вложен, если условия

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

, чем я разделяю выражение следующим шаблоном;

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

но somecases если-то процессы могут быть использованы один в другом - Например (вложенном 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, как я могу решить эту проблему с регулярным выражением?

ответ

1

Вы не можете. По дизайну регулярные выражения не могут иметь дело с рекурсией.

Для получения дополнительной информации вы можете прочитать первый ответ здесь: Can regular expressions be used to match nested patterns?

И да, я знаю, что некоторые специальные «регулярные выражения» действительно позволяют рекурсии. Однако в большинстве случаев это означает, что вы делаете что-то ужасное.

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 

Этот код соответствия вашей вложенную структуру. Теперь плохие новости: вы не можете захватить «состояние» и «контент» с других глубин одним шаблоном! Способ сделать это, чтобы сделать рекурсивную функцию, которая повторяет шаблон по «контенту» и останавливается, когда нет более вложенных «если»

Имейте в виду, что этот подход имеет огромную сложность (в алгоритмическом смысле) и что лучший способ (вы знаете) использовать DOM

Смежные вопросы