分析一个复杂正则表达式

(?'Open'([\s]?)#item((-(?<itemName>.+?))?))(?<itemContentTpl>\s[\s\S]+?)(?'-Open'[\s]#item([\s]?))(?(Open)(?!))

一、表达式1:([\s]?)#item((-(?<itemName>.+?))?)

  最开始的?'Open' 属于平衡组的知识,如果匹配到表达式1,则把Open压入栈中

  ([\s]?)表示匹配0或1次任何空白字符

  (?<itemName>.+?) 匹配一个除“\n”和"\r"之外的任何单个字符一次或多次,并存入itemName组里

  ((-(?<itemName>.+?))?)  有-开头的0次或1次

二、表达式2:(?<itemContentTpl>\s[\s\S]+?)

  \s[\s\S]+? 表示 匹配全部字符1次或多次,加了?表示惰性匹配,表达式2在表达式1和3之间,那就是取出表达式1和3之间的不可见字符开头后的所有字符

三、表达式3:(?'-Open'[\s]#item([\s]?))

  ?'-Open' 也属于平衡组的知识,如果匹配到表达式3,则把open弹出栈

四、表达式4:(?(Open)(?!))

  如果栈中还有open,则无条件匹配失败,跟?'Open' 配合,表示有开头就必须有结尾,可以当作有左括号就必须有一个右括号匹配

五、总结

  整个正则可以匹配位于两个#item之间的所有字符,把-之后的和\n\r之前的字符存进itemName组里,把两个#item之间的所有字符存进itemContentTpl组里

  比如下面字符串,itemName组里的值是:“123”     itemContentTpl组里的值是:"\r\n#{aa}        #{bb}    #{cc}     #{dd}\r\n#{ee}      \r"

  而#{a} #{b} #{c} #{d}#{e} 没有匹配上,因为它并不是在两个#item之间

 

 

  

string str = @“#item-123
#{aa} #{bb} #{cc} #{dd}
#{ee}
#item
#item
#{a} #{b} #{c} #{d}
#{e}
”;

 

posted @ 2022-03-24 10:23  暗,伏!  阅读(208)  评论(0编辑  收藏  举报