2012-08-11 125 views
5

我想匹配(從類文件中選擇)methodsname,屬性名稱和字段名稱。c#正則表達式 - 從類文件(.cs)中選擇類屬性名稱,方法名稱和字段

這是示例類:

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類: 公衆的Perl()公共靜態DoSomething的(字符串測試),但我想這樣的結果:的Perl()DoSomething的()。所以 - 我的代碼匹配很好,但我想要顯示的結果就像我在前面的句子中寫的 。
  • 如何選擇屬性?結果顯示:類型和屬性 名稱。因此,從實例級結果將是:字符串名稱
  • 如何選擇帶結果的字段:type field_name。在出情況下, 將是:字符串_name
+1

可能是[This SO Answer](http://stackoverflow.com/a/11647554/1495442) – Ria 2012-08-11 12:03:19

+0

的重複在代碼文件上使用反射而不是正則表達式編譯的類可能有意義嗎?你會得到更可靠的結果(即你不必擔心你的正則表達式命令是否覆蓋了每種可能的情況),它可以用於任何.NET語言,而不僅僅是C#。 – 2012-08-11 12:06:56

+0

所以我得到.cs類文件的文件夾。我可以編譯它「在空氣中」,然後使用反射?如何動態編譯類例如是否有我可以使用的函數?例如。在按鈕上單擊comile選定文件夾中的所有cs文件? – born2fr4g 2012-08-11 12:30:31

回答

3

使用此Regex

的方法

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

並獲得團體名爲methodNameparameterTypeparameter

和領域:

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

,並獲得團體名爲typename

例如你的方法的代碼可以是這樣的:

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

您可以使用Irony - .NET Language Implementation KitCodePlex上了。

+0

但是屬性和文件呢? ;) – born2fr4g 2012-08-11 12:31:23

+0

能見度範圍'internal'呢? – 2012-08-11 14:52:04

+0

我不能使用諷刺;)。我在我的應用程序中使用NET 2.0。感謝您的字段正則表達式代碼。我將嘗試修改它以匹配屬性(使用get或set ** **}) – born2fr4g 2012-08-12 07:31:18

2

正如在評論你的答案說明,更可靠的方法是編譯的.cs文件,然後使用反射來詢問類型的會員你有興趣在這將涉及以下內容:

  1. 使用C#編譯器(csc.exe)來編譯你的文件。 MSDN包含有用的examples and hints。您可以手動執行此操作,或者,如果您想自動整理所有內容,則可以使用Process class以編程方式執行csc.exe。
  2. 使用Assembly.LoadFile()方法加載生成的程序集。
  3. 您現在可以使用反射到get types從大會和interrogate他們。

編輯:作爲替代CSC.EXE,你可以使用CodeDOM - 有一個包含所有你需要的example

+0

前一段時間我問過類似的問題,關於如何使用反射方法獲取參數值,但很遺憾沒有有用的答案。這甚至有可能嗎?因爲這將是取代正則表達式的方法。 – formatc 2012-08-11 14:54:10

+0

@ user1010609我不明白這與這個問題有什麼關係 - 但發佈鏈接,我可以看看它。 – 2012-08-11 15:27:20

+0

這是不相關的,但讓我們說他想要做這樣的事情'Console.WriteLine(_name);',有沒有辦法得到'_name'值是什麼?如果硬編碼像Console.WriteLine(「John」);'?因爲正則表達式可以輕鬆地做到這一點,但讓其他事情變得更加複雜,只是想讓他指向正確的方向。 – formatc 2012-08-11 16:01:54

0

像C#這樣的語言接受太多的語法語法變體,只能使用正則表達式進行解析。在正則表達式之上,你需要一個上下文語法分析器。

我會給Roslyn一個嘗試:它是一個C#編譯器,其內部可從您的代碼訪問。請Roslyn解析代碼並查詢您需要的任何信息。

0

我建議看看Microsoft.VisualStudio.CSharp.Services.Language命名空間和其他Visual Studio擴展性功能。這將消除編譯的需要。