micahblu
micahblu

Reputation: 5212

Regular expression to capture html tag style syntax using double brackets

I'm writing up Yet Another Template Engine in PHP. Should Mustache.php really be 1.6mb?? I want something lighter and completely workflow Agnostic. What happened to the good ole days of including a vendor file and using it?

Anyhow, the syntax is simple and such I have a very simple working preg_replace working for simple variables i.e. [[variable]]

However I'm running into an issue whereas I'd like to to catch encapsulated conditional content. I.e

[[#if this == 'that']] To be seen or not to be that is the question! [[/if]]

Below is my current regex and its very close, however I can't seem to work out the proper rules for the closing [[/if]] tag;

It captures past the closing tag :(

preg_match('/\\[\\[#if(.+)\\]\\][^\\[\\]\\/](.+)\\[\\[\\/if\\]\\]/s', $template, $ifmatches);

Any help would be greatly appreciated!

Upvotes: 1

Views: 133

Answers (1)

Vasili Syrakis
Vasili Syrakis

Reputation: 9591

This is my modification to your regex:

\[\[#(\w+)\s(.*?)\]\](.*?)\[\[\/\1\]\]

Changes that I made:

  • I removed the literal text for "if" and instead matched it with a short-hand character class \w between 1 and unlimited times. I placed this into a capture group with the backreference number of 1.
  • As per your regex, I matched a space after the tag name... and then matched any character, between 0 and unlimited times, as few times as possible (.*?) with backreference number 2.
  • The characters between the tags are also matched as few times as possible with the ? quantifier and placed into backreference 3.
  • In the closing tag, I used a backreference to capture group 1, so that the tags are always consistent.

The thing that really makes this work better is the ? quantifier. It turns the expression "lazy" which is a good thing, because it doesn't "over-reach".

Here's a demo to show how it works:

'?' Quantifier demonstration

Upvotes: 1

Related Questions