Ifs pattern using regex

Hi everyone, I am working on a PHP application that needs to parse a .tpl file with HTML in it, and I am doing it so that HTML can have variables and basic if statements. The if statement looks like this: `

<!--if({VERSION} == 2)-->
Hello World
<!--endif -->

      

To analyze this, I tried using preg_replace

with no luck. The pattern I tried was

/<!--if\(([^\]*)\)-->([^<]*)<!--endif-->/e

which is replaced by

if($1) { echo "$2"; }

Any ideas as to why this won't work and what I can do to get it up and running?

0


source to share


3 answers


I think you wanted to do this:

'/<!--if\(([^)]*)\)-->([^<]*)<!--endif-->/'

      

There is only one character class in your regex:

[^\]*)\)-->([^<]

      

Here's what's going on:



  • The first closing square bracket is escaped with a backslash, so it matches literally.
  • The brackets that were supposed to close the first capture group and open the second are also taken literally; there is no need to avoid parses within a character class.
  • The first hyphen is accepted as a metacharacter; it forms the range [) * +, -]
  • The second opening square bracket is taken as a literal square bracket because it is inside a character class.
  • The second caret is taken as literal caret because it is not the first character in the class.

So, after removing the duplicates and sorting the characters in their ASCII order, your character class is equivalent to this:

[^()*+,\-<>\[\]^]

      

And the parentheses outside of the character class are still balanced, so regex compilation, but it doesn't even come close to what you wanted.

0


source


You have a space between endif

and -->

, but your regex doesn't allow that.



By the way, this seems terribly insecure ... Is there a reason you don't use a built-in templating engine like Smarty?

+3


source


Checking your regex I can see that the backslash is being applied to the square bracket. To use a backslash inside square brackets inside a quoted string, you need to execute it twice:

'/<!--if\(([^\\\]*)\)-->([^<]*)<!--endif-->/e'

      

But I don't know why you are inventing a new logical template structure when solutions such as Smarty and PHP exist.


Here's the test code in response to the comments below.

testinput.tpl

<!--if({VERSION} == 2)-->
Hello World
<!--endif-->

      

match.php

<?php
$template = file_get_contents('testinput.tpl');
print preg_match('/<!--if\(([^\\\]*)\)-->/e', $template) . "\n";
print preg_match('/<!--endif-->/e', $template) . "\n";
print preg_match('/<!--if\(([^\\\]*)\)-->([^<]*)<!--endif-->/e', $template) . "\n";

      

test run :

$ php match.php
1
1
1

      

+2


source







All Articles