0

I'm using a template system. In this template system I am using the structure shown below for if-else conditions;

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

than I'm separating the expression with the following pattern;

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

but somecases if-else processes can be used one within the other (nested? - recusirve?) For example;

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

In this cases pattern gives following results.

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

(so without this)

    condition 1 text more
</if>

Without using domdocument how can I solve that problem with regex ?

2 Answers 2

1

You can't. By design, regular expressions cannot deal with recursion.

For more information, you might want to read the first answer here: Can regular expressions be used to match nested patterns?

And yes, I know that some special "regular expressions" do allow for recursion. However, in most cases, this means that you are doing something horrible.

Sign up to request clarification or add additional context in comments.

Comments

0

You can. "By design, regular expressions cannot deal with recursion." is true, but PCRE offers more features than a strict regular expression language. It's the reason why the term "regular expression" is inexact to refer to "regex" in many languages.

The way to do that:

$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

This code match your nested structure. Now, the bad news: You can't capture "condition" and "content" from the other depths with a single pattern! A way to do that is to make a recursive function that retries the pattern on "content" and stops when there's no more nested "if".
For a replacement, you can also build a pattern that describes the innermost "if" tag (a pattern that forbids other nested "if") and apply it in a do..while loop.

Keep in mind that this approach has an high complexity (in the algorithmic sense) and that a better way is to use the DOM.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.