1

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

我的字符串:

@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@
4

1 回答 1

1

您没有正确使用平衡组。必须使用平衡组使用捕获将某些值推入堆栈并与其他捕获一起从堆栈中删除,然后需要一个条件构造来检查组堆栈是否为空,如果不是,则匹配失败强制回溯。

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

(?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@)

请参阅正则表达式演示。但是,在这里编写自定义解析器可能会成为更好的方法。

图案细节

  • (?s)- 单行模式(.匹配换行符)
  • (?<match>- 外部组“匹配”的开始
  • @if\(- 文字字符序列@if(
  • (?<statement>[^)]*)- 组“语句”捕获 0+ 个字符,而不是)
  • \)\s*{\s* - ), 0+ 个空格, {, 0+ 个空格
  • (?<ifblock>.*?)- 捕获任何 0+ 字符的组“ifblock”,尽可能少到第一个...
  • \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+ 空格,endif@序列或...的字符
      • (?<a>)@if\s*\(|- 组“a”将@if, 0+ 个空格推(入堆栈
      • (?<-a>)\}\s*endif@- }, 0+ 个空格,endif@从“a”组堆栈中删除
    • )*- 轮换组结束
    • (?(a)(?!))if- 有条件地检查和的平衡量endif是否匹配
  • \}\s*endif@- }, 0+ 个空格,endif@
  • )- 外部“匹配”组的结尾。
于 2017-03-22T09:59:18.483 回答