1

I am in a middle of writing a project which has a template engine and some new defined tags like LOOP or IF and etc ...

Assume this is a block of template that PHP should process and convert to a PHP script:

<LOOP products>
    {{name}}
    {{id}}

    <LOOP comments>
        {{name}}
    </LOOP>

    {{quantity}}
</LOOP>

I want to convert all {{variables}} to print them out based on the properties of the loop variable, But I want to exclude inner LOOP tags for each loop.

Because the first LOOP's {{name}} tag should be $product->name and second LOOP's name should be $comment->name

This regex will convert all {{variables}} to first LOOP variable which is product.

$pattern = '/\s*\{\{(\w+)+\}\}\s*/';

Above output is

<LOOP products>
    {{name}} // $product->name
    {{id}} // $product->id

    <LOOP comments>
        {{name}} // $product->name ! <-- this {{variable}} should 
                 // be exculde of first loop converting.
    </LOOP>

    {{quantity}} // $product->quantity
</LOOP>

UPDATE

I also tried this:

(?!<LOOP[^>]*?>)\{\{(\w+)+\}\}(?![^<]*?</LOOP>)
// this works for 2 level of nested LOOPs.
// when I add another LOOP as third level ...
// ... contents of level2 are changing too, which is not corrent.
// ONLY first level should change.
5
  • So what do you want the resulting PHP to look like for your example above? Commented Jul 28, 2014 at 10:55
  • I updated post, I need to exclude inner LOOPs and their content in regex. Commented Jul 28, 2014 at 11:00
  • It's still not clear exactly what the output should be. Should the inner loop remain unchanged or be removed? Could you write the exact output you are expecting? Commented Jul 28, 2014 at 11:21
  • the exact output is based on many conditions. BUT yes, I want the inner levels to remain unchanged. Commented Jul 28, 2014 at 11:23
  • I think that (*SKIP)(*F) could be somehow used but I don't know how to do it in this case Commented Jul 28, 2014 at 11:32

2 Answers 2

2

you should first create a data tree from your text. after that you can apply the variable substitutions.

  1. search for the loop tags and split the document so you get a data structure like this:

    • LOOP: products
      • TEXT: {{name}} {{id}}
      • LOOP: comments
        • TEXT: {{name}}
      • TEXT: {{quantity}}
  2. go through all LOOP data entries and substitute all their TEXT-strings with your regex

  3. rebuild a text document by traversing the data structure

this will give you great flexibility when enhancing your template system. it will also be easier to maintain.

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

Comments

1

Dreamlab is correct: don't try to parse XML/HTML with regex. Use an XML/HTML parser to process the data, and exclude the inner loops that way. This is an especially complex problem to solve with regexes that becomes surprisingly easy when you use the proper tools for the job. In your case, throw your XML into SimpleXML and iterate through the tree or use some XPath.

When regexes are your hammer, everything sometimes looks like a nail, but it's a really bad tool for a lot of situations - and a particularly terrible tool for your problem. Regex just isn't built to solve this kind of problem, and you will find nothing but pain if you attempt to do so.

A sidenote: It seems like you might be trying to invent a new templating language as well. If that's the case, you probably don't need to. Bundle Mustache or Smarty or Twig or any of the other numerous templating engines that already exist and are well-tested and functional.

It sounds like you may be writing some sort of framework, so this may not be applicable, but depending on your use case, you can just use PHP, since PHP is a templating language:

<?php for($products as $p): ?>
    <?=$p['name']?>
    <?=$p['id']?>

    <?php for($p['comments'] as $c): ?>
        <?=$c['name']?>
    <?php endforeach ?>

    <?=$p['quantity']?>
<?php endforeach ?>

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.