I try to create my own markup language for displaying page templates from the database. The template can be used "conditions". They look like:
{@IF(PAYMENT_METHOD_ID==0):}
<!-- code here -->
{@ENDIF;}
Where PAYMENT_METHOD_ID is variable .
When the page generated, we look by regular expressions "conditions" , check them and make to them proper action.
template_html = Regex.Replace(template_html, @"{@IF\(['""]?([^'""]*?)['""]?\s*(==|!=)\s*['""]?([^'""]*?)['""]?\):}([\s\S]*?){@ENDIF;}", x =>
{
/* LOGIC WITH "CONDITION" */
});
The problem occurs with nested "conditions". Ie "condition" embedded in another "condition" . For example:
{@IF(PAYMENT_METHOD_ID==0):}
{@IF(DELIVERY_METHOD_ID==1):}
<!-- code here -->
{@ENDIF;}
{@ENDIF;}
In this case , the regular expression finds the first {@ENDIF}.
**{@IF(PAYMENT_METHOD_ID==0):}
{@IF(DELIVERY_METHOD_ID==1):}
<!-- code here -->
{@ENDIF;}**
{@ENDIF;}
How to build a regular expression to search for only pairs of "conditions"?
Thanks!
OK, you can do this since the .NET regex engine can handle recursive matches, but it's a little complicated. I'm getting the feeling that a parser would be better suited for this scenario (you need to write one anyway)...
Regex regexObj = new Regex(
@"{@IF\(['""]?([^'""]*?)['""]?\s* # Match IF statement, first part.
(==|!=) # Match comparison operator.
\s*['""]?([^'""]*?)['""]?\):} # Match rest of IF statement.
(?> # Then either match (possessively):
(?: # the following group which matches
(?!{@IF\(|{@ENDIF;) # only if we're not at the start of an IF/ENDIF
. # any character
)+ # once or more
| # or
{@IF\( (?<Depth>) # match inner IF (and increase nesting counter)
| # or
{@ENDIF; (?<-Depth>) # match inner ENDIF (and decrease the counter).
)* # Repeat as needed.
(?(Depth)(?!)) # Assert that the nesting counter is at zero.
{@ENDIF;} # Then match ENDIF.",
RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline);