RegEx 匹配 VB.NET 选择大小写,不带其他大小写

发布于 2024-10-05 15:50:30 字数 961 浏览 8 评论 0原文

我正在寻找一个正则表达式,它将找到其中没有 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
 Case :
  Select Case
   Case : Something
  End Select
  Case Else : SomethingElse
End Select

在这种情况下,它应该只匹配内部 Select Case,因为外部有它的 Case Else

Select Case
 Case :
  Select Case
   Case : Something
   Case Else : SomethingElse
  End Select
End Select

应该匹配整个块,因为内部有 Else 但外部没有。

Select Case
 Case :
  Select Case
   Case : Something
   Case Else : SomethingElse
  End Select
  Case Else : SomethingElseOutter
End Select

不应匹配,因为内部和外部选择都有 Case Else

I'm looking for a RegEx that will find Select Case Statements that have no Case Else in them.

Here's what I came up with so far

(?sm)^\s*Select Case.*(?<!^\s*Case Else.*)End Select

This one works perfectly except for cases that may have nested statements.

in my attempt to use balance groups, I came up with the following

Select Case(?>Select Case(?<DEPTH>)|End Select(?<-DEPTH>)|.?)*?(?(DEPTH)(?!))End Select

Which correctly finds balanced groups of Select Case/End Selects but I'm having a hard time getting it to work with the (?

Heres some sample data:

Select Case
 Case :
  Select Case
   Case : Something
  End Select
  Case Else : SomethingElse
End Select

In this case it should match just the inner Select Case because the Outter has it's Case Else

Select Case
 Case :
  Select Case
   Case : Something
   Case Else : SomethingElse
  End Select
End Select

Should match then entire block because the inner has the Else but the outter doesnt.

Select Case
 Case :
  Select Case
   Case : Something
   Case Else : SomethingElse
  End Select
  Case Else : SomethingElseOutter
End Select

Should not match because both inner and outter selects have a Case Else

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

简单爱 2024-10-12 15:50:30

正则表达式

^[ \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)

在 regexstorm.net 上测试


描述

正则表达式匹配 Select Case,然后尝试消耗尽可能少的行尽可能直到找到 End Select。对于每一行:

  • 如果有嵌套的 Select Case,它会在 (?Select[ ]Case)
  • (?(nested)< 中创建一个 Capture /code>true|false) 是一个 IF 子句:
    • 如果有nested的捕获(即在嵌套语句内),它可以在(?<-nested>End[ ]Select)?时减去捕获匹配(可选组)。
    • 或者,如果没有捕获(即在主语句中),则该行不应是 Else 语句 (?!Case[ ]Else)

这是平衡组背后的逻辑。如果它与嵌套的 Select Case 匹配,则会创建一个新的捕获,如果它与 End Select 匹配,则会减去最后一个捕获。因此,仅在外部组中不会存储捕获。

我们在模式的末尾使用 (?(nested)(?!)|[ \t]*End[ ]Select)。如果有捕获,它会转到 (?!) (永远无法匹配),失败并回溯以继续消耗更多行。但如果没有捕获,它可以匹配 [ \t]*End[ ]Select (或回溯并消耗更多行)。

就是这样。

但请注意,如果有两个没有 Case Else 的 Select 语句嵌套在另一个语句中,则只有外部语句会匹配。如果您有兴趣匹配两者,请

(?=(previous pattern))

使用 Match.Groups(1) 来匹配文本。

Regex

^[ \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'

One-liner:

^[ \t]*Select Case.*\n(?>(?>[ \t]*)(?>(?<nested>Select Case)|(?(nested)(?<-nested>End Select)?|(?!Case Else))).*\n)*?(?(nested)(?!)|[ \t]*End Select)

Test on regexstorm.net


Description

The regex matches Select Case and then it tries to consume as few lines as it can until it finds an End Select. For each line:

  • If there's a nested Select Case, it creates a Capture in (?<nested>Select[ ]Case)
  • (?(nested)true|false) is an IF clause that:
    • If there's a capture for nested (i.e. inside a nested statement), it could substract a capture when (?<-nested>End[ ]Select)? matches (optional group).
    • Or if there isn't a capture (i.e. in the main statement), the line should not be an Else statement (?!Case[ ]Else).

This is the logic behind balancing groups. If it matches a nested Select Case, it creates a new capture, and if it matches an End Select it substracts the last capture. Therefore, only in the outer group there will be no captures stored.

We use that at the end of the pattern with (?(nested)(?!)|[ \t]*End[ ]Select). If there's a capture it goes to (?!) (which can never match), fails and backtracks to keep consuming more lines. But if there are no captures, it can match [ \t]*End[ ]Select (or backtrack and consume more lines as well).

That's it.

Notice though that if there are two Select staments without a Case Else, nested one in another, only the outer statement will be matched. if you're interested in matching both, use

(?=(previous pattern))

and use Match.Groups(1) to get the text matched.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文