c# regex - select class properties names, methods

2019-04-29 21:00发布

I want to match (select from class file) methodsname, properties name and fields name.

This is example class:

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;
    }
}

I got code for the methods:

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

And i got questions:

  • this above regex code gets all methods and it works pretty well but also i want it to select method name but without parameters and accessors. So from exaplmce class using my code result will be: public Perl() and public static doSomething(string test) but i want that kind of result: Perl() and doSomething(). So - my code matches good but i want result to be displayed just like I wrote in previous sentence.
  • how to select properties ? with result displayed: type and property name. So from exaple class result will be: string Name
  • how to select fields with result: type field_name. In out case it will be: string _name

4条回答
等我变得足够好
2楼-- · 2019-04-29 21:26

Use this Regex

for methods

(?: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*)+\)

and get groups named methodName and parameterType and parameter.

and for fields:

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

and get groups named type and name.

for example your code for methods can be like this:

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++;
    }
}

You can use Irony - .NET Language Implementation Kit from codeplex too.

查看更多
【Aperson】
3楼-- · 2019-04-29 21:37

I suggest looking at Microsoft.VisualStudio.CSharp.Services.Language namespace and other Visual Studio Extensibility functionality. This would eliminate the need to compile.

查看更多
太酷不给撩
4楼-- · 2019-04-29 21:38

A language such as C# accepts too many variations in statements syntax to be parsed using regular expressions only. On top of regexes, you need a contextual grammar parser.

I would give Roslyn a try: It's a C# compiler whose internals are accessible from your code. Ask Roslyn to parse the code and query it about whatever info you need.

查看更多
甜甜的少女心
5楼-- · 2019-04-29 21:40

As stated in comments to your answer, much more reliable method is to compile your .cs files and then use reflection to interrogate types for members you are interested in. It will involve the following:

  1. Use C# compiler (csc.exe) to compile your files. MSDN contains helpful examples and hints. You could do this manually, or, if you want to automatize the whole thing, you could execute csc.exe programmatically with Process class.
  2. Use Assembly.LoadFile() method to load the resulting assembly.
  3. You can now employ reflection to get types from the assembly and interrogate them.

EDIT: As an alternative to csc.exe, you could use CodeDOM - there is an example that contains all you need.

查看更多
登录 后发表回答