我想通过Regex解析VB6代码。然而,对于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
我基本上有这两个问题:如何编写与Sub定义匹配的Regex,并在其定义之上包含所有commment(和空)行?如何防止通过注释禁用或包含在字符串中的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
。
感谢您的帮助!
答案 0 :(得分:2)
我怀疑除了最简单的情况之外,这对所有人来说都是不可能的。使用regexp,您无法解析递归结构,语言(如VB)将具有递归功能。有关详细信息,请参阅this CodingHorror blog entry。
除非你的案例非常简单,否则我认为某种形式的解析器将成为前进的方向。
答案 1 :(得分:2)
为什么要解析此代码?如果您正在尝试创建自己的编译器,那么您需要的不仅仅是正则表达式。如果你正在编写一个语法高亮和预先输入完成的编辑器,正则表达式可以在第一个,但不是第二个上做得很好。
那就是说,我对你的正则表达式看到的最大问题是你没有正确处理续行。这个:\s+_?
匹配一个或多个空格字符,可选地后跟下划线。但如果有一个下划线,则应该跟一个你不匹配的换行符。这很容易补救 - \s+(_\s+)?
- 但我不确定你是否需要那样具体。我怀疑这一点:[\s_]+
也会这样做。
至于避免在注释和字符串中明显的子/函数声明,最简单的方法是仅在左边距处匹配它们,可能还有一些标签或空格用于缩进。我知道,这是作弊,但无论你做什么,它都可能足够好。当我为EditPad Pro编写Java file navigation scheme时,我非常依赖这个技巧。如果不使用大量的噱头和简化假设,你就不能用正则表达式来做这种事情。试试这个正则表达式:
^(?>('(?<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
进行编译。
答案 2 :(得分:1)
你知道,最终会出现正则表达式还不够的时候。解析这个级别就是其中之一。
考虑编写一个简单的真实解析器,可能使用递归下降。
答案 3 :(得分:1)
不要试图写一个正则表达式为你做这个(它本身不能)。你需要的是一个解析器。可能最简单的解决方案是使用recursive descent parser。我不使用C#,但快速搜索出现了Spart。
答案 4 :(得分:0)
鉴于Visual Basic的复杂性和内在性,您可能需要使用tokenizer / parser解析代码。您不能依赖正则表达式所有;)
对于它的价值,VB formal grammar is available here。玩得开心!