Skip to main content
 首页 » 编程设计

c#之跨越多行的正则表达式/识别注释行

2024年01月29日27tintown

我想通过 Regex 解析 VB6 代码。然而,作为 Regex 的新手,我遇到了一些有关要使用的 regex 的问题。目前,我在识别这些结构时遇到了问题:

' Subs 
' Sub Test 
Private Sub Test(ByVal x as Integer) 
    'Private Sub Test(ByVal y as Integer) 
    Dim dummy as String 
    dummy = "Private Sub Test(ByVal y as Integer)" 
End Sub  

我基本上有这 2 个问题:如何编写匹配 Sub 定义的正则表达式,并在其定义上方包含所有注释(和空)行?我怎样才能防止被注释禁用或包含在字符串中的 Sub 定义不匹配? 另外,我需要支持跨越多行的定义,例如:

' Subs 
' Sub Test 
Private Function Test2( _ 
   ByVal x as Integer _ 
) As Long 
    'Private Sub Test(ByVal y as Integer) 
    Dim dummy as String 
    dummy = "Private Sub Test(ByVal y as Integer)" 
End Function 

如有任何提示,我们将不胜感激。我提出的解决方案不适用于多行或捕获不止一个 Sub 定义。由于贪婪匹配,它然后只匹配到最后一个 End Sub 事件的结尾。

我在 C# 中的尝试目前看起来像这样:

(('(?<comment>[\S \t]+[\n\r]+))*((?<accessmodifier>(Private|Public))\s+_?)(?<functiontype>(Sub|Function))\s+_?(?<name>[\S]+)\((?<parameters>[\S \t]*)\)([ \t]+As[ \t]+(?<returntype>\w+))?)|(?<endfunction>End (Sub|Function)) 

我正在使用 Multiline、Singleline、IgnoreCase、ExplicitCapture。

感谢您的帮助!

请您参考如下方法:

为什么要解析这段代码?如果您正在尝试创建自己的编译器,那么您需要的不仅仅是正则表达式。如果您正在编写一个带有语法高亮和预输入补全功能的编辑器,正则表达式可以在第一个方面做得很好,但在第二个方面就不行了。

就是说,我发现您的正则表达式存在的最大问题是您没有正确处理续行。这:\s+_? 匹配一个或多个空白字符,可选地后跟一个下划线。但是如果有下划线,它后面应该跟一个换行符,而你不匹配它。这很容易补救 - \s+(_\s+)? - 但我不确定您是否需要那么具体。我怀疑这个:[\s_]+ 也可以。

至于避免在注释和字符串中出现明显的子/函数声明,最简单的方法是仅在左边距处匹配它们,可能还有一些制表符或空格用于缩进。这是作弊,我知道,但不管你在做什么,它可能已经足够好了。当我编写 Java file navigation scheme 时,我非常依赖这个技巧。适用于 EditPad Pro。如果不使用大量的噱头和简化假设,你就不能用正则表达式做这种事情。试试这个正则表达式:

^(?>('(?<comment>.*[\n\r]+))*) 
[ \t]*(?<accessmodifier>(Private|Public)) 
[\s_]+(?<functiontype>(Sub|Function)) 
[\s_]+(?<name>\S+) 
[\s_]*\((?<parameters>[^()]*)\) 
([\s_]+As[\s_]+(?<returntype>\w+))? 
| 
^[ \t]*(?<endfunction>End (Sub|Function))

当然,您需要先重新组装它。它应该使用 Multiline、IgnoreCase 和 ExplicitCapture 选项进行编译,但不能使用 Singleline。