创建标记语言 - 条件

时间:2013-12-24 12:56:36

标签: c# regex markup

我尝试创建自己的标记语言,以便从数据库中显示页面模板。 模板可以使用“条件”。他们看起来像:

{@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;}

如何构建正则表达式以仅搜索成对的“条件”?

谢谢!

1 个答案:

答案 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);