使用正则表达式查找特定段
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)(?!))
- 条件检查 if
和 endif
的余额是否匹配
\}\s*endif@
- }
, 0+ 个空格, endif@
)
- 外部 "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@
我需要匹配:@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)(?!))
- 条件检查if
和endif
的余额是否匹配
\}\s*endif@
-}
, 0+ 个空格,endif@
)
- 外部 "match" 组结束。