我正在寻找一个RegEx,它会找到其中没有Case Else的Select Case语句。
这是我到目前为止所提出的
(?sm)^\s*Select Case.*(?<!^\s*Case Else.*)End Select
除了可能有嵌套语句的情况外,这个工作正常。
在我尝试使用余额组时,我想出了以下内容
Select Case(?>Select Case(?<DEPTH>)|End Select(?<-DEPTH>)|.?)*?(?(DEPTH)(?!))End Select
哪个正确找到了Select Case / End Selects的平衡组,但是我很难让它与(?
以下是一些样本数据:
Select Case
Case :
Select Case
Case : Something
End Select
Case Else : SomethingElse
End Select
在这种情况下,它应该只匹配内部的Select Case,因为Outter有它的Case Else
Select Case
Case :
Select Case
Case : Something
Case Else : SomethingElse
End Select
End Select
应该匹配整个区块,因为内部有Else但是outter不存在。
Select Case
Case :
Select Case
Case : Something
Case Else : SomethingElse
End Select
Case Else : SomethingElseOutter
End Select
不应该匹配,因为内部和外部选择都有一个Case Else
答案 0 :(得分:0)
<强>正则表达式强>
^[ \t]*Select[ ]Case.*\n # Start of 'Select Case' statement
(?> # REPEAT as few as possible
(?>[ \t]*) # whitespace at beginning of line
(?> # And
(?<nested>Select[ ]Case) # there's a nested Select (+1 balancing group)
| # Or
(?(nested) # If inside a nested statement
(?<-nested>End[ ]Select)? # match 'End Select' (-1 balancing group)
| # Else
(?!Case[ ]Else) # it can't match a 'Case Else'
) #
) #
.*\n # Consume the whole line (go to next line)
)*? # END REPEAT
(?(nested)(?!)| # If inside a nested statement, it can't match
[ \t]*End[ ]Select) # if outer statement, match the 'End Select'
一衬垫:
^[ \t]*Select Case.*\n(?>(?>[ \t]*)(?>(?<nested>Select Case)|(?(nested)(?<-nested>End Select)?|(?!Case Else))).*\n)*?(?(nested)(?!)|[ \t]*End Select)
<强>描述强>
正则表达式与Select Case
匹配,然后尝试使用尽可能少的行,直到找到End Select
。对于每一行:
Select Case
,则会在(?<nested>Select[ ]Case)
(?(nested)
true |
false )
是一个IF子句:
nested
的捕获(即在嵌套语句中),它可以在(?<-nested>End[ ]Select)?
匹配时(可选组)减去捕获。(?!Case[ ]Else)
。这是balancing groups背后的逻辑。如果它与嵌套的Select Case
匹配,则会创建一个新的捕获,如果它与End Select
匹配,则会减去最后一次捕获。因此,只有在外部组中才会存储捕获。
我们在(?(nested)(?!)|[ \t]*End[ ]Select)
模式的末尾使用它。如果有捕获它会转到(?!)
(它永远不会匹配),失败并回溯以继续消耗更多行。但如果没有捕获,它可以匹配[ \t]*End[ ]Select
(或回溯并消耗更多行)。
那就是它。
请注意,如果有两个没有Case Else的Select staments,则嵌套在另一个中,只会匹配外部语句。如果您对匹配两者感兴趣,请使用
(?=(previous pattern))
并使用Match.Groups(1)
来匹配文字。