.NET字符串解析库,或用于解析.NET代码文件的正则表达式。

3

我希望能够解析vb.net代码文件,以便检查子程序、函数(包括注释)、私有变量等的集合。

我可以打开实际的源代码文件。

例如,如果我有以下代码:

Public Function FunctionOne(arg1 As String, arg2 as String) as Integer
   here is some code
   ''//here are some comments
End Function

Public Sub FunctionOne(arg1 As integer, arg2 as integer)
   here is some code
   ''//here are some comments
End Sub

我希望能够解析出所有的子程序和函数以及在Public Function和End Function之间的所有代码(实际上,将有选择地包含仅在其中的代码或整个函数定义会更好)。
这似乎需要某种解析库,或者相当不错的正则表达式技能。
有什么建议吗?
更新: 我正在尝试实现的主要目标是解析源代码,因此反射也许只是用于获取函数列表等等,我知道如何做到这一点,但我正在努力找到一种适当的方法来解析源代码。

很好的问题。这是我在C#领域一直在寻找的东西,但除了SharpDevelop之外,迄今为止没有什么运气。祝你好运! - Jeff Yates
7个回答

6
从您的程序中运行编译并在编译后的库上使用反射,这种方式可行吗?
请查看此微软讨论了解详细信息!

我认为这是一个不错的想法。有谁比编译器更擅长解析代码呢? - Ben S
这可能是阅读函数参数和类型、返回类型等的方法,但它并不能帮助获取底层源代码,而这正是我试图实现的主要目标。 - tbone
我不太明白你想要实现什么。底层源代码是可用的,只需在.cs源文件上执行File.Open()即可......那么你确切想做什么? - Brann

3
你应该使用随 SharpDevelop 一起提供的 NRefactory 库。

这个库允许你解析 VB 或 C# 文件。它主要用于代码转换器,但也可以用于代码分析(这是我们公司所做的)。

使用以下代码:

Imports System

Class MainClass
  Public Function FunctionOne(arg1 As String, arg2 As String) As Integer
    Return Int32.Parse(arg1) + Int32.Parse(arg2)
  End Function

  Public Sub FunctionOne(arg1 As Integer, arg2 As Integer)
    Return
  End Sub

End Class

您可以获得这种结果(我在这里使用了NRefactoryDemo应用程序) alt text http://img15.imageshack.us/img15/3564/stackoverflownrefactory.png

1

1

这段代码比较粗糙,但基本上实现了我想要做的事情:

Private _SourceCode As String = Nothing
Private ReadOnly Property SourceCode() As String
                Get
                    If _SourceCode = Nothing Then
                        Dim thisCodeFile As String = Server.MapPath("~").ToString & "\" & Type.GetType(Me.GetType.BaseType.FullName).ToString & ".aspx.vb"
                        _SourceCode = My.Computer.FileSystem.ReadAllText(thisCodeFile)
                    End If
                    Return _SourceCode
                End Get
End Property  

Private Function extractProcedureDefinition(ByVal procedureName As String) As String
   Return extractStringContents(Me.SourceCode, "Sub " & procedureName & "()", "End Sub", True)
End Function  

Private Function extractFunctionDefinition(ByVal procedureName As String) As String
   'TODO: This works now, but wouldn't if we wanted includeTags = False, as it does not properly handle the "As xxxxx" portion
   Return extractStringContents(Me.SourceCode, "Function " & procedureName, "End Sub", True)
End Function

    Private Function extractStringContents(ByVal body As String, ByVal openTag As String, ByVal closeTag As String, ByVal includeTags As Boolean) As String
                Dim iStart As Integer = body.IndexOf(openTag)
                Dim iEnd As Integer = body.IndexOf(closeTag, iStart)
                If includeTags Then
                    iEnd += closeTag.Length
                Else
                    iStart += openTag.Length
                End If
                Return body.Substring(iStart, iEnd - iStart)
    End Function  

1

madgnome 对我来说非常准确! 我想解析C#代码并确定命名空间、类、成员和程序集之间的关系。 NRefactory和NRefactoryDemo应用程序正是我需要解决这个问题的东西,而且很容易上手!

非常感谢!


0

我认为你正在寻找Microsoft.CSharp.CSharpCodeProvider,它接受一个文件并直接访问C#代码生成器和编译器。我想它也可以接受字符串。

MSDN: http://msdn.microsoft.com/en-us/library/microsoft.csharp.csharpcodeprovider.aspx

编辑:

在问题更新后,我发现这不相关了,但仍然可能利用此对象从公共方法中提取源代码,就像您所需的那样。我会再进一步调查...


0

你可以编译这个东西,然后使用Reflector工具。我们都认为Reflector主要是一个GUI工具,它有一个很棒的功能,就是可以反编译.NET程序集。它可以从DLL或EXE文件中生成源代码。但是Reflector本身也可以通过编程方式进行控制。因此,您的应用程序可以:

  • 将源代码编译成程序集
  • 调用Reflector,要求它进行反编译
  • 通过编程方式操作Reflector的输出-获取函数列表以及与其相关联的反编译源代码。

示例

这种方法可能无法满足需求-因为您从Reflector获得的源代码不是原始源代码,而是反编译源代码。注释将消失,并且反编译不是100%忠实于原始代码。虽然在功能上等效,但并非完全相同。

无论如何,值得一看。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接