views:

1562

answers:

4

Hi,

I'm having difficulty throwing away the bits of the expression I don't want, and keeping the bits I do.

The problem is - given the input string:

{if cond}foo{else}bar{/if}

I'd like just to have:

0: {if cond}foo{else}bar{/if}
1: cond
2: foo
3: bar

And for the input string:

{if cond}foo{/if}

I'd like just to have:

0: {if cond}foo{else}bar{/if}
1: cond
2: foo
3:

The regex I've got at present looks like this:

\{if ([a-z0-9]+)\}([^\{]*?)(((?:\{else\})?)(.*?)?)\{/if\}

I get the following data back:

0: {if cond}foo{else}bar{/if}
1: cond
2:
3: foo{else}bar
4:
5: foo{else}bar

Which would require further parsing of the foo{else}bar bit to get the respective values.

Is my regex anywhere near close?

I'm not too concerned about the sort of data this might be run over - including { in the body of an if statement is allowed to break the regex. The values of foo and bar can be anything that does not include a {.

Thanks,

Dom

+5  A: 

This should work :

{if\s+([^}]*)}([^{]*)(?:{else}([^{]*))?{/if}

Escape it according to your needs

Diadistis
That works beautifully - thanks! It does add an extra part (the whole expression is in 0 and 1), but I can live with that.
Dominic Rodger
Just get rid of the outermost set of parentheses.
Alan Moore
...yeah, like that! :)
Alan Moore
+2  A: 

What about this?

\{if ([a-z0-9]+)\}([^\{]*)(?:\{else\})?([^\{]*)\{/if\}
Martin Brown
That works beautifully, and doesn't have the extra part that Diadistis' has, so I'll mark this as accepted. Thank you!
Dominic Rodger
+1  A: 

Regex tester. It uses the .NET regex engine, but it might come in handy.

Adam Neal
A: 

It's note stated in your question, but from the tags it seems that you use the Boost C++ library.

Maybe it is also of interest for you to look at the Boost.Spirit library (included in Boost). Spirit.Qi allows you to parse complex data, while the grammar is looks like EBNF. While the companion Spirit.Karam alows to define the output format, again in EBNF like syntax.

With this library you can generate an AST from the templated document, manipulate it and then generate the output document.

Beside of the documentation of Boost.Spirit, there are some greate slides from 2007 and 2008 wich give a fairly good introduction.

jk