【问题标题】:Regex C# - how to match methods and properties names of a class正则表达式 C# - 如何匹配类的方法和属性名称
【发布时间】:2012-07-25 06:21:22
【问题描述】:

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

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

对于类名,我正在使用这种正则表达式:(?+ 对于我尝试这样的方法:[^\ s]+(?=() 但这将选择所有具有 ( 的文本。对于方法,我需要选择具有 ( 和访问器的那一行像 public、private 和 protected。如何在最终匹配中不包含它?我只需要括号内的方法名称和参数。

【问题讨论】:

    标签: c# regex pattern-matching


    【解决方案1】:

    编辑:使用这个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*)+\)
    

    并获取名为 methodNameparameterTypeparameter 的组。

    你的代码可以是这样的:

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

    【讨论】:

    • 不错,但是void test(string name, int value)public void test(string name, out int value) 呢?它们都是有效的声明?
    • 另外两个:void test(string name, int[] value)void test(string name, params int[] value)。我不想成为一个痛苦的人,我只是想表明我的观点:现在可以的事情会在你没有想到的情况下分崩离析:)
    • 它很棒:)。如何选择没有像公共这样的关键字但只有属性名称和方法名称的文本(在最终匹配中)?
    【解决方案2】:

    使用反射怎么样?

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

    【讨论】:

    • 我认为他试图解析的类不是正在执行的程序集的一部分,但是动态编译代码并使用反射可能是个好主意...
    • 更新答案以包括动态编译。
    • 我无法尝试,但我喜欢它 :) +1 来自我!
    • 但是,我可以在 .cs 文件上使用它吗?我上面的代码,在哪里添加 .cs 文件的路径?编辑好的对不起你刚刚更新了你的代码。伟大的 :)。伙计们,我有一个普遍的问题:我可以从什么构建类图 - 从 dll 或 .cs 文件?我现在真的不知道。
    • 如果您使用的是 Visual Studio,您可以添加一个新的“类图”项并将您的类拖到上面,代码必须编译。见msdn.microsoft.com/en-us/library/ff657806.aspx如果没有,可以查看外部工具,见stackoverflow.com/questions/1600802/…
    【解决方案3】:

    使用正则表达式会很难做到这一点。

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

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

    您还应该编写大量单元测试 - 修改正则表达式时很容易破坏某些内容。

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

    【讨论】:

    • 感谢小费,但我需要自动执行此操作;)。我需要将 .cs 文件中的信息写入 txt/xml 文件。老实说访问器和关键字,这项任务应该不会那么难。或者,也许您知道更简单的方法?从cs(类文件)属性和方法名称中检索)
    • @born2fr4g:为什么不是自动的? :) 检查那个库和它附带的例子,它真的很值得,不应该花很长时间。正则表达式的风险在于,在一种情况下有效的东西不够通用,无法处理另一种有效的情况..
    • 但我有 2.0 NET 项目,但 Irony 需要 NET 4.0 以及如何使用它?这有点缺乏文档;)
    • 嗯...你应该说它是 .net 2.0 的东西:P
    • 对此很抱歉,但还是感谢您的提示 :) - 我会检查这个具有讽刺意味的库。你有任何示例或扩展文档的链接吗?
    猜你喜欢
    • 2016-01-22
    • 1970-01-01
    • 2018-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-18
    • 2018-10-11
    • 2011-11-27
    相关资源
    最近更新 更多