1

我想匹配方法名称(带参数)和属性名称。我不想在匹配中包含访问器。例如,我得到了这样的课程:

public class test
{
    public static string NA = "n/a";

    public static DateTime DateParser(string dateToBeParsed)
    {
        DateTime returnValue = new DateTime();
        DateTime.TryParse(dateToBeParsed, GetCulture(), System.Globalization.DateTimeStyles.AssumeLocal , out returnValue);
        return returnValue;
    }
}

对于类名,我使用这种正则表达式:(?<=class\s)[^\s] + 对于我尝试这样的方法:[^\s]+(?=()但这将选择所有具有(的文本。对于方法,我需要选择具有(以及诸如公共、私有和受保护的访问器之类的访问器。如何在不包括在最终匹配中的情况下执行此操作?我只需要括号内的方法名称和参数。

4

3 回答 3

3

编辑:使用这个Regex

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

并获取名为methodNameandparameterType和的组parameter

你的代码可以是这样的:

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++;
    }
}
于 2012-07-25T10:17:55.417 回答
3

使用反射怎么样?

class Program
{
    static void Main(string[] args)
    {
        string assemblyName = Path.Combine(Path.GetTempPath(), string.Format("temp{0}.dll", Guid.NewGuid()));
        CSharpCodeProvider codeProvider = new CSharpCodeProvider();
        CompilerParameters compilerParameters = new CompilerParameters(new string[]
        {
            "System.dll",
            "Microsoft.CSharp.dll",
        }, assemblyName);

        CompilerResults cr = codeProvider.CompileAssemblyFromSource(compilerParameters, File.ReadAllText("Program.cs"));

        if (cr.Errors.Count > 0)
        {
            foreach (CompilerError error in cr.Errors)
            {
                Console.WriteLine(error.ErrorText);
            }
        }
        else
        {
            AppDomain appDomain = AppDomain.CreateDomain("volatile");
            Proxy p = (Proxy)appDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(Proxy).FullName);
            p.ShowTypesStructure(assemblyName);
            AppDomain.Unload(appDomain);
            File.Delete(assemblyName);
        }
        Console.ReadLine();
    }
}

public class Proxy : MarshalByRefObject
{
    public void ShowTypesStructure(string assemblyName)
    {
        Assembly assembly = Assembly.LoadFrom(assemblyName);
        Type[] types = assembly.GetTypes();
        foreach (Type type in types)
        {
            Console.WriteLine(type.Name);
            MethodInfo[] mis = type.GetMethods();
            foreach (MethodInfo mi in mis)
            {
                Console.WriteLine("\t" + mi.Name);
            }
        }
    }
}
于 2012-07-25T10:25:28.810 回答
1

用正则表达式来做到这一点相当困难。

您可以尝试创建一个适当的解析器。Irony库易于使用,其中一个示例是 C# 解析器。

但是,如果您想使用正则表达式,可以尝试使用Expresso 之类的工具,它可以帮助您测试和构建正则表达式。

你还应该写很多单元测试——当你修改一个正则表达式时很容易破坏一些东西。

很抱歉没有提供“使用此表达式”之类的“具体”帮助,但我认为如果您想避免使用解析器,那真的需要做很多工作:)

于 2012-07-25T06:37:37.063 回答