regex 从cs文件获取方法的内容

m0rkklqb  于 2023-02-05  发布在  其他
关注(0)|答案(7)|浏览(126)

我有一个要求,就是把一个cs文件中的每个方法的内容都转换成一个字符串,我所寻找的是当你输入一个cs文件时,返回一个字典,其中方法名作为键,方法体作为值。
我试过正则表达式和反射都没有成功,有人能帮忙吗?
谢谢

6xfqseft

6xfqseft1#

我不知道它对你是否有用,但是VisualStudioAddins包含一个EnvDTE对象,它让你可以完全访问VB和C#语言解析器。
几年前我就稍微提到过它,我不知道它有多难用,也不知道它有多有效,但它确实看起来会给你你所需要的。

    • 代码模型允许自动化客户端避免实现Visual Studio语言的分析器**,以便发现项目中的高级定义,如类、接口、结构、方法、属性等。

如果你阅读全文,它会告诉你如何从一个文件中提取函数的全文
希望这有帮助:)

euoag5mw

euoag5mw2#

假设文件是有效的(即编译),您可以从将整个文件读入字符串开始。

我从你的问题中推断出你只对方法名感兴趣,而对类名不感兴趣,那么你需要一个正则表达式来给出 public的所有示例|受保护的|private,可选关键字virtual/override etc,MethodName,可选参数,。如果有编码约定,这将有所帮助,因此您可以假设所有方法定义始终在一行中,而不是分散在几行中。
一旦你有了这些,就只需要计算{和}来得到函数体了。
最后一个建议:小心假设。他们有咬你屁股的坏习惯。

**EDIT:**哎哟,忘了注解了!如果你在方法体的注解中有括号,你的计数可能会出错。所以你需要从源代码中去掉所有注解作为你的第一步。

7gyucuyw

7gyucuyw3#

一般来说,你要解决的问题是以编译器的方式解析C#代码,然后保存函数的内容,而不是生成代码。因此,作为你解决方案的背景,你应该看看c#语法以及如何解析它们。
根据StingyJack的说法,一个简单的方法是创建一个只识别函数定义的正则表达式。然后你可以假设中间的所有东西都是函数体。然而,这种假设不会处理一个文件中的多个类,甚至是类末尾的尾随}。要处理这样的事情,你必须设计一个c#编译器。因为处理完整的C#语法是将正确地标识C#认为什么是函数的唯一事情。

b1payxdu

b1payxdu4#

找到函数头之后,计算大括号的个数,直到找到函数的结尾。

idfiyjo8

idfiyjo85#

定制的解析器将是最好的选择。正如Blair在给StingyJack的评论中所说,用regex解析代码非常困难。我曾经尝试过一次,尽管可以用NET匹配平衡括号,但转义注解和字符串要复杂得多。
解析器应该会使事情变得简单得多。参见antlr获得一个好的生成器。
至于反射,我相信你可以尝试编译代码(只要你有所有必要的依赖项),然后像反射器一样访问它的内容。

pxy2qtax

pxy2qtax7#

您可以使用Microsoft.CodeAnalysis.CSharp执行此操作
下面的例子应该能让你了解,它假设你在一个命名空间里有一个类:

var output = new Dictionary<string, string>();

var csFilePath = @"C:\File.cs";
var csFileContent = File.ReadAllText(csFilePath);
SyntaxTree tree = CSharpSyntaxTree.ParseText(csFileContent );
CompilationUnitSyntax root = tree.GetCompilationUnitRoot();
var nds = (NamespaceDeclarationSyntax)root.Members[0];
var cds = (ClassDeclarationSyntax) nds.Members[0];

foreach(var ds in cds.Members){
    //Only take methods into consideration
    if(ds is MethodDeclarationSyntax){
        var mds = (MethodDeclarationSyntax) ds;
        
        //Method name
        var methodName = ((SyntaxToken) mds.Identifier).ValueText;
        
        //Method body (including curly braces)
        var methodBody = mds.Body.ToString();
        
        output.Add(methodName, methodBody);
    }
}

相关问题