使用正则表达式查找特定段

Find specific segments using regex

我有一个字符串,我想将其分成特定的段,但由于同一模式出现两次,我无法匹配字符串的正确段。

我的字符串:

@if(text.text isempty){<customer_comment>@cc{txt_without_comments}cc@</customer_comment>}else{@if(text.answer=='no'){<customer_comment>@{text.text}</customer_comment>}else{<answer>@{text.text}</answer>}endif@}endif@

我需要匹配:@if(text.text isempty){@cc{txt_without_comments}cc@}else{....}endif@

而不是 else 块中的嵌套点。

这是我不完整的正则表达式:

(?<match>(?<open>@if\((?<statement>[^)]*)\)\s*{)(?<ifblock>(.+?)(?:}else{)(?<elseblock>.*))(?<-open>)}endif@)

此正则表达式在 ifblock 组中过于贪婪,它应该在第一个}else{ 模式处停止。

编辑: 这是我想要产生的确切结果:

match: @if(text.text isempty){<customer_comment>@cc{txt_without_comments}cc@</customer_comment>}else{@if(text.answer=='no'){<customer_comment>@{text.text}</customer_comment>}else{<answer>@{text.text}</answer>}endif@}endif@

statement: text.text isempty

ifblock: <customer_comment>@cc{txt_without_comments}cc@</customer_comment>

elseblock: @if(text.answer=='no'){<customer_comment>@{text.text}</customer_comment>}else{<answer>@{text.text}</answer>}endif@

您没有使用 balancing groups correctly. Balancing groups must be used to push some values into the stack using a capture and removed from the stack with other captures, and then a conditional construct 有必要检查组堆栈是否为空,如果不是,则匹配失败以强制回溯。

因此,如果正则表达式是您匹配这些字符串的唯一方法,请使用以下内容:

(?s)(?<match>@if\((?<statement>[^)]*)\)\s*{\s*(?<ifblock>.*?)\s*}\s*else\s*{\s*(?<elseblock>@if\s*\((?:(?!@if\s*\(|\}\s*endif@).|(?<a>)@if\s*\(|(?<-a>)\}\s*endif@)*(?(a)(?!)))\}\s*endif@)

参见regex demo。但是,在这里编写自定义解析器可能是更好的方法。

图案详情:

  • (?s) - 单行模式开启(. 匹配换行符)
  • (?<match> - 外部组的开始 "match"
  • @if\( - 文字字符序列 @if(
  • (?<statement>[^)]*) - 组 "statement" 捕获除 )
  • 之外的 0+ 个字符
  • \)\s*{\s* - ), 0+ 个空格, {, 0+ 个空格
  • (?<ifblock>.*?) - 组 "ifblock" 捕获任何 0+ 个字符,尽可能少直到第一个...
  • \s*}\s*else\s*{\s* - 0+ 个空格,},0+ 个空格,else,0+ 个空格,{,0+ 个空格
  • (?<elseblock>@if\s*\((?:(?!@if\s*\(|\}\s*endif@).|(?<a>)@if\s*\(|(?<-a>)\}\s*endif@)*(?(a)(?!))) - 组 "elseblock" 捕获:
    • @if\s*\( - @if, 0+ 个空格, (
    • (?: - 交替组的开始,即重复 0+ 次
      • (?!@if\s*\(|\}\s*endif@).| - 任何不以 @if、0+ 空格、( 序列开始且不以 }、0+ 空格、[=35= 开始的字符] 序列或...
      • (?<a>)@if\s*\(| - 组 "a" 将 @if、0+ 空格和 ( 推入堆栈
      • (?<-a>)\}\s*endif@ - },0+ 个空格,endif@ 从 "a" 组堆栈中删除
    • )* - 交替组结束
    • (?(a)(?!)) - 条件检查 ifendif 的余额是否匹配
  • \}\s*endif@ - }, 0+ 个空格, endif@
  • ) - 外部 "match" 组结束。