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]+(?=()しかし、これはすべてを選択しますそのテキストには(。メソッドの場合、(および public、private、protected などのアクセサーを持つ行を選択する必要があります。最終的な一致にこれを含めずにそれを行うにはどうすればよいですか?メソッド名と括弧内のパラメーターのみが必要です。

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ライブラリは使いやすく、その例の 1 つは C# パーサーです。

ただし、正規表現を使用したい場合は、正規表現のテストと構築に役立つExpressoなどのツールを使用してみてください。

また、多くの単体テストを作成する必要があります。正規表現を変更すると、何かを壊すのはかなり簡単です。

「この式を使用してください」というような「具体的な」ヘルプを提供できなくて申し訳ありませんが、パーサーを避けたい場合は、本当に大変な作業だと思います:)

于 2012-07-25T06:37:37.063 に答える