c#regex – 从类文件(.cs)中选择类属性名称,方法名称和字段
我想匹配(从类文件中选择)methodsname,属性名称和字段名称。
这是示例类:
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类的结果将是: string Name
- 如何选择带有结果的字段:type field_name。 在out的情况下,它将是: string _name
使用此正则Regex
方法
(?:public\s|private\s|protected\s|internal\s)?[\s\w]*\s+(?\w+)\s*\(\s*(?:(ref\s|/in\s|out\s)?\s*(?\w+)\s+(?\w+)\s*,?\s*)+\)
并获取名为methodName
和parameterType
和parameter
。
和领域:
(?:public\s|private\s|protected\s)\s*(?:readonly\s+)?(?\w+)\s+(?\w+)
并获取名为type
和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+(?\w+)\s*\(\s*(?:(ref\s|/in\s|out\s)?\s*(?[\w\?\[\]]+)\s+(?\w+)\s*,?\s*)+\)")) { var methodName = match.Groups["methodName"].Value; var typeParameterPair = new Dictionary(); 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语言实现工具包 。
正如您对答案的评论中所述,更可靠的方法是编译.cs文件,然后使用reflection来查询您感兴趣的成员的类型。它将涉及以下内容:
- 使用C#编译器(csc.exe)编译文件。 MSDN包含有用的示例和提示 。 您可以手动执行此操作,或者,如果要自动完成整个操作,可以使用
Process
类以编程方式执行csc.exe。 - 使用Assembly.LoadFile()方法加载生成的程序集。
- 您现在可以使用reflection从程序集中 获取类型并查询它们。
编辑:作为csc.exe的替代品,您可以使用CodeDOM – 有一个示例包含您需要的所有内容。
诸如C#之类的语言在语句语法中接受太多变体,仅使用正则表达式进行解析。 在正则表达式之上,您需要一个上下文语法分析器。
我会试试Roslyn :它是一个C#编译器,其内部可以从你的代码中访问。 请求Roslyn解析代码并查询您需要的任何信息。
我建议查看Microsoft.VisualStudio.CSharp.Services.Language
命名空间和其他Visual Studio Extensibilityfunction。 这将消除编译的需要。