Regular Expression to match {if cond}foo{else}bar{

2019-06-12 07:32发布

问题:

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

回答1:

What about this?

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


回答2:

This should work :

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

Escape it according to your needs



回答3:

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



回答4:

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.