我尝试创建自己的标记语言,以便从数据库中显示页面模板。 模板可以使用“条件”。他们看起来像:
{@IF(PAYMENT_METHOD_ID==0):}
<!-- code here -->
{@ENDIF;}
PAYMENT_METHOD_ID可变的地方。
当页面生成时,我们按正则表达式“条件”查看,检查它们并使它们正确行动。
template_html = Regex.Replace(template_html, @"{@IF\(['""]?([^'""]*?)['""]?\s*(==|!=)\s*['""]?([^'""]*?)['""]?\):}([\s\S]*?){@ENDIF;}", x =>
{
/* LOGIC WITH "CONDITION" */
});
嵌套“条件”会出现问题。即“条件”嵌入另一个“条件”。例如:
{@IF(PAYMENT_METHOD_ID==0):}
{@IF(DELIVERY_METHOD_ID==1):}
<!-- code here -->
{@ENDIF;}
{@ENDIF;}
在这种情况下,正则表达式会找到第一个{@ENDIF}。
**{@IF(PAYMENT_METHOD_ID==0):}
{@IF(DELIVERY_METHOD_ID==1):}
<!-- code here -->
{@ENDIF;}**
{@ENDIF;}
如何构建正则表达式以仅搜索成对的“条件”?
谢谢!
答案 0 :(得分:1)
好的,你可以这样做,因为.NET正则表达式引擎可以处理递归匹配,但它有点复杂。我觉得解析器更适合这种情况(你还需要写一个)...
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);