我想通过 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。
