tags:

views:

46

answers:

2

Is there a way to find custom tags in regexp I.e. match

{a}sometext{/a}  

As well as

{c=#fff}sometext{/c}  

So that it finds the entire block of inner content? The problem is the sometext could have another tag as in:

{a=http://www.google.com}{b}Hello, world{/b}{/a}  

The only solutions I can come up with would match from {a... to .../b} when I want {a... to .../a} is there a single regexp solution, or would it be best to match the start, and then use another method to find the end from the back up, and grab it out that way? I'm using PHP 5.2 so I have all the options that entails.

+1  A: 

This works:

$subject = 'bla bla{a=http://www.google.com}{b}Hello, world{/b}{/a} bla';
$regex = '~\\{a(?:=[^}]+)?\\}(.*?)\\{/a\\}~';
preg_match($regex, $subject, $matches);
var_dump($matches);

gives:

array(2) {
  [0]=>
  string(48) "{a=http://www.google.com}{b}Hello, world{/b}{/a}"
  [1]=>
  string(19) "{b}Hello, world{/b}"
}

BEGIN EDIT You could make the regex more general with backreferences

$regex = '~\\{([a-z]+)(?:=[^}]+)?\\}(.*?)\\{/\\1\\}~';

but in that case, I have no idea how to match inner tags of arbitrary depth. END EDIT

However, I strongly recommened against using a regular expression for this purpose. I suggest you iterate over the string, one array at a time and use an auxiliary stack to keep track of the tags you find (use array_push, array_pop and end for peek).

Artefacto
Thanks for the working regex, but I don't quite understand your suggestion. if it would be more efficient, then I would love to use it. do you know of any articles about it?
Rixius
Google for "parser tag nested stack" or something similar, you'll find articles on how to parse nested tags.
Artefacto
+1  A: 

Sounds like you are trying to do what MediaWiki already does with wiki markup language. I would suggest using their parser and their markup or if you choose to roll your own you might find inspiration from seeing how they do it.

Manual for Parser.php

Source for Parser.php

Flash84x
This is exactly what I was trying to find, Thanks! I am trying to roll my own, for the learning experience as well as because I only want certain features.
Rixius