C# 嵌套相同条件时正则表达式不起作用

C# 嵌套相同条件时正则表达式不起作用,c#,regex,C#,Regex,背景:我只是在玩弄一个简单模板的想法,它只提供if/for/render,看看它有多可行,在我的个人项目中使用它是否有意义。与使用Novelocity、剃刀或其他任何东西相反 我写了一个正则表达式: (?:(?:(?\[如果(?[a-zA-Z0-9\.]+)\](?[^\[]*)+(?:[^\[]*(?\[如果\]结束])+(?(打开)(?!) 与示例文本一起使用时: [if variable3]{{variable3}}[end if] [如果变量为1] {{variable1} [如果变

背景:我只是在玩弄一个简单模板的想法,它只提供if/for/render,看看它有多可行,在我的个人项目中使用它是否有意义。与使用Novelocity、剃刀或其他任何东西相反

我写了一个正则表达式:

(?:(?:(?\[如果(?[a-zA-Z0-9\.]+)\](?[^\[]*)+(?:[^\[]*(?\[如果\]结束])+(?(打开)(?!)
与示例文本一起使用时:


[if variable3]{{variable3}}[end if]
[如果变量为1]
{{variable1}
[如果变量为2]

{{variable2}} [如有需要,请结束] [如有需要,请结束]
我得到了两个匹配项,如果第二个匹配项有效,我可以解析内部捕获

问题是,如果我有多个嵌套匹配项。因此给定:


[if variable3]{{variable3}}[end if]
[如果变量为1]
{{variable1}
[如果变量为2]

{{variable2}} [如有需要,请结束] [如果变量为4]
{{variable4}} [如有需要,请结束] [如果可变5]
{{variable5}} [如有需要,请结束] [如有需要,请结束]
我最后得出的结论是,第一次捕获是正确的,然后是所有3次单独捕获,而不是第二次匹配的外部捕获

如果我扩展捕获以忽略内部内容的
\[
,则会导致第一个匹配和第二个匹配合并为一个匹配:(

有人知道如何解决这个问题吗?(如果您对如何进行模板制作有更好的了解,请在评论中详细介绍)

您可以使用

@"(?s)\[if\s+(?<if>[^][]+)](?<fullBody>(?>(?:(?!\[if\s|\[end\ if]).)+|(?<-open>)\[end\ if]|(?<open>)\[if\s+(?<if>[^][]+)])*(?(open)(?!)))\[end\ if]"
@“(?s)\[if\s+(?[^][]+)](?(?>(?:(?!\[if\s\[end\if])+(?)\[end\if](?)\[if\s+(?[^][]+)*(?(open)(?!)\[end\if]。”

详细信息(注意,由于x修饰符的缘故,您可以在C代码中使用它):

@(?sx)#上的单线和忽略模式空白标志
\[if\s+#“[if”和1+空格
(?[^][]+)#“如果”组:除“]”以外的一个或多个字符
]#a“]”字符
(?#包含所有嵌套if块的组“fullBody”
(?>#原子群的开始
(?:(?!\[if\s |\[end\if])+|#任何字符,1+次,不启动“[if”或“[end if]”子字符串,或。。。
(?)\[end\if]|#“[end if]”子字符串,并且从组“open”中弹出一个项,或者
(?)\[if\s+(?[^][]+)]#组“打开”:“[if”,1+空格,组“if”:1+除“[”和“]”以外的字符,然后是“]”字符
)*#重复原子群模式0次或以上
(?(打开)(?!)#条件:如果组“打开”的堆栈上有任何项目,则失败并返回
)#全身组结束
\[end\if]“#”[end if]”子字符串
如果您不关心If块是否嵌套在哪个块中,则可以使用此正则表达式的变体获得If块的完整列表:

var pattern = @"(?s)(?=(?<ifBlock>\[if\s+(?<if>[^][]+)](?<fullBody>(?>(?:(?!\[if\s|\[end\ if]).)+|(?<-open>)\[end\ if]|(?<open>)\[if\s+(?<if>[^][]+)])*(?(open)(?!)))\[end\ if]))";
var模式=@“(?s)(?=(?\[if\s+(?[^][]+))](?(?(?:(?!\[if\s\[end\if]))+(?)\[end\if](?)\[if\s+(?[^][]+)*((开放式)(?!)\[end\if])”;

上面的模式只是用另一个命名的捕获组包装,并放在正向前瞻中。虽然匹配值始终为空,但组将保存您可能需要的所有值。

我建议查看XML解析器。尝试使用正则表达式解析HTML是。@Lewsterin但他没有解析HTML?@Lewsterin我不是p通过分析HTML,我正在解析自己的语法。如何从HTML文档中提取数据不被视为解析?您需要能够区分您感兴趣的数据和HTML标记。我对解析的理解是否错误?您可以使用
(?s)\[if\s+(?[^][+])(?>(?:(?!\[if\s\[end\if])正确匹配所有块+|(?)。
var pattern = @"(?s)(?=(?<ifBlock>\[if\s+(?<if>[^][]+)](?<fullBody>(?>(?:(?!\[if\s|\[end\ if]).)+|(?<-open>)\[end\ if]|(?<open>)\[if\s+(?<if>[^][]+)])*(?(open)(?!)))\[end\ if]))";