5

我想匹配(从类文件中选择)方法名、属性名和字段名。

这是示例类:

class Perl
{
    string _name;
    public string Name { get; set; }
    public Perl()
    {
    // Assign this._name
    this._name = "Perl";
    // Assign _name
    _name = "Sam";

    // The two forms reference the same field.
    Console.WriteLine(this._name);
    Console.WriteLine(_name);
    }
    public static string doSomething(string test)
    {
        bla test;
    }
}

我得到了方法的代码:

(?:public|private|protected)([\s\w]*)\s+(\w+)\s*\(\s*(?:\w+\s+(\w+)\s*,?\s*)+\)

我有问题:

  • 上面的正则表达式代码获取所有方法,它工作得很好,但我也希望它选择方法名称但没有参数和访问器。所以从 exaplmce 类使用我的代码结果将是: public Perl()public static doSomething(string test)但我想要那种结果: Perl()doSomething()。所以 - 我的代码匹配得很好,但我希望像我在前一句中写的那样显示结果。
  • 如何选择属性?显示结果:类型和属性名称。所以从 exaple 类结果将是:字符串名称
  • 如何选择具有结果的字段:键入 field_name。在这种情况下,它将是:string _name
4

4 回答 4

3

用这个Regex

对于方法

(?:public\s|private\s|protected\s|internal\s)?[\s\w]*\s+(?<methodName>\w+)\s*\(\s*(?:(ref\s|/in\s|out\s)?\s*(?<parameterType>\w+)\s+(?<parameter>\w+)\s*,?\s*)+\)

并获取名为methodNameandparameterType和的组parameter

对于字段:

(?:public\s|private\s|protected\s)\s*(?:readonly\s+)?(?<type>\w+)\s+(?<name>\w+)

并获取名为typeand的组name

例如,您的方法代码可以是这样的:

var inputString0 = "public void test(string name, out int value)\r\nvoid test(string name, int value)";
foreach (Match match in Regex.Matches(inputString0, @"(?:public\s|private\s|protected\s)?[\s\w]*\s+(?<methodName>\w+)\s*\(\s*(?:(ref\s|/in\s|out\s)?\s*(?<parameterType>[\w\?\[\]]+)\s+(?<parameter>\w+)\s*,?\s*)+\)"))
{
    var methodName = match.Groups["methodName"].Value;
    var typeParameterPair = new Dictionary<string, string>();
    int i = 0;
    foreach (var capture in match.Groups["parameterType"].Captures)
    {
        typeParameterPair.Add(match.Groups["parameterType"].Captures[i].Value, match.Groups["parameter"].Captures[i].Value);
        i++;
    }
}

您也可以使用来自codeplex的Irony - .NET Language Implementation Kit

于 2012-08-11T12:02:32.187 回答
2

正如对您的答案的评论中所述,更可靠的方法是编译您的 .cs 文件,然后使用反射来询问您感兴趣的成员的类型。它将涉及以下内容:

  1. 使用 C# 编译器 (csc.exe) 编译您的文件。MSDN 包含有用的示例和提示。您可以手动执行此操作,或者,如果您想使整个事情自动化,您可以使用Processclass以编程方式执行 csc.exe 。
  2. 使用Assembly.LoadFile()方法加载生成的程序集。
  3. 您现在可以使用反射从程序集中获取类型询问它们。

编辑:作为 csc.exe 的替代方案,您可以使用CodeDOM - 有一个示例包含您需要的所有内容。

于 2012-08-11T14:43:06.800 回答
0

像 C# 这样的语言接受的语句语法变化太多,只能使用正则表达式进行解析。在正则表达式之上,您需要一个上下文语法解析器。

我想试试Roslyn:它是一个 C# 编译器,它的内部结构可以从您的代码中访问。让 Roslyn 解析代码并查询您需要的任何信息。

于 2012-08-12T06:28:20.060 回答
0

我建议查看Microsoft.VisualStudio.CSharp.Services.Language命名空间和其他Visual Studio 可扩展性功能。这将消除编译的需要。

于 2012-08-12T06:53:03.917 回答