2011-01-22 34 views
0

我試圖創建一個C#程序,它提取* .cs文件中#region標記中包含的代碼。我或多或少只是希望能夠排除我正在處理的代碼,並讓它可以作爲文本訪問到其他程序。解析代碼文件中的#區域

有沒有什麼已經存在,完成了這個?

說我有這樣的代碼:

#region ClassName.Test() 
public static void Test() 
{ 
    //Some method that does stuff 
} 
#endregion 

我希望能夠提取

public static void Test() 
{ 
    //Some method that does stuff 
} 
從*的.cs爲 string

當我指定我期待爲Class.Test()

回答

3

如果您不擔心嵌套的#regions。這段代碼可以做到這一點。 調用GetCodeRegions()傳入您的代碼字符串(您通過使用File.ReadAlltext獲得)來獲取所需區域內的代碼片段列表。

static void Main(string[] args) 
    { 
     var code = @"#region ClassName.Test() //Some method that does stuff 
      //some stuff 
      #endregion 

      #region ClassCName.Random() 
      public static void Test() 
      { 
       //Some more stuff 
      } 
      #endregion"; 

     List<string> codeRegions = GetCodeRegions(code); 
    } 

    private static List<string> GetCodeRegions(string code) 
    { 
     List<string> codeRegions = new List<string>(); 

     //Split code into regions 
     var matches = Regex.Matches(code, "#region.*?#endregion", RegexOptions.Singleline); 

     foreach (var match in matches) 
     { 
      //split regions into lines 
      string[] lines = match.ToString().Split(new string[] { "\r\n" }, StringSplitOptions.None); 

      if (lines.Length > 2) 
      { 
       codeRegions.Add(string.Join("\r\n", lines, 1, lines.Length - 2)); 
      } 

     } 

     return codeRegions; 
    } 
1

如果您不介意潛在的麻煩問題,那麼您可以簡單地打開文件並搜索您要查找的關鍵字。

問題來自於這樣的事實:字符串可能包含您正在查找的信息,但不打算進行搜索。您可以嘗試忽略字符串,但由於「使用(\」,「」等等)的所有方式,這會變得有點複雜。

如果您可以安全地忽略C#中的字符串,那麼只需打開文本文件,逐行搜索您要查找的內容(string.Find)。

如果您希望做到這一點,那麼使用CodeDOM是一種好的選擇!

1

假設我們有一個字符串classcode整個代碼

我們可以這樣做

串[]區域= Regex.Split( 「#區域」,classcode);

現在區域字符串數組將包含您在訪問數組時可以訪問的區域代碼。

,你將不得不從陣列中各個串是沒有這麼麻煩刪除區域名稱和#endregion

0

我想改善迄今提供的答案。 爲什麼? 他們都不會輕易讓開發人員識別代碼段來自哪個區域。爲了公平起見,我準備了一個比較目前提供的三種解決方案的代碼。 我的測試還證明不應該使用https://stackoverflow.com/users/418281/ankush-roy提供的解決方案,因爲它也可以返回不屬於某個區域的代碼。

首先結果:---------

//****** Result:: Regex.Split(code, "#region") 
public class TestRegionParsing 
{ 
    private void Test1() 
    { 
     //this code should not be read 
    } 
    ClassName.Test()  
    //Some method that does stuff 
    //some stuff 
    #endregion ClassName.Test() 
    ClassCName.Random() 
    public static void Test() 
    { 
     //Some more stuff 
    } 
    #endregion ClassCName.Random() 
    private void Test2() 
    { 
     //this code should not be read 
    } 
    ClassCName.Random() 
    public static void Test3() 
    { 
     //Some more stuff 
    } 
    #endregion 
} 
//****** Result:: GetCodeRegions(code) 
//Some method that does stuff 
//some stuff 
    public static void Test() 
{ 
    //Some more stuff 
} 
    public static void Test3() 
{ 
    //Some more stuff 
} 
//****** Result:: Utils.GetRegionsFromCShapFile(csharpFinePath) 
Region name converted:1.cs 
    //Some method that does stuff 
    //some stuff 
Region name converted:2.cs 
    public static void Test() 
    { 
     //Some more stuff 
    } 
Region name converted:3.cs 
    public static void Test3() 
    { 
     //Some more stuff 
    } 

,是由兩個代碼解析的CS文件:

public class TestRegionParsing 
{ 
    private void Test1() 
    { 
     //this code should not be read 
    } 

    #region ClassName.Test()  
    //Some method that does stuff 
    //some stuff 
    #endregion ClassName.Test() 

    #region ClassCName.Random() 
    public static void Test() 
    { 
     //Some more stuff 
    } 
    #endregion ClassCName.Random() 

    private void Test2() 
    { 
     //this code should not be read 
    } 

    #region ClassCName.Random() 
    public static void Test3() 
    { 
     //Some more stuff 
    } 
    #endregion 
} 

現在我已經實現

代碼
/// <summary> 
    /// For a given source code, it parses all regions and creates a dictionary where 
    /// Key=region name and Value=list of region's code lines.<para /> 
    /// Known Issue: This method dos not work with regions within regions. <para /> 
    /// </summary> 
    /// <param name="sourceCodeFileName">string - full source code .cs path</param> 
    /// <returns>Key=region name and Value=list of region's code lines.</returns> 
    public static Dictionary<string, List<string>> GetRegionsFromCShapFile(string sourceCodeFileName) 
    { 
     FileInfo f = new FileInfo(sourceCodeFileName); 
     if (f.Length > ONE_Gb) 
     { 
      throw new ArgumentOutOfRangeException(string.Format("File:{0} has size greater than {1}{2}", MAX_STORAGE, STORAGE_UNIT)); 
     } 
     Dictionary<string, List<String>> regions = new Dictionary<string, List<string>>(); 
     string[] readLines = File.ReadAllLines(sourceCodeFileName); 
     List<string> current_list = null; 

     foreach (string l in readLines) 
     { 
      if (l != null) 
      { 
       if (l.TrimStart().StartsWith("#region", StringComparison.CurrentCultureIgnoreCase)) 
       { 
        string key = string.Format("{0}.cs", ExtractNumber(l.Trim())); 
        if (regions.ContainsKey(key)) 
        { 
         throw new ArgumentException(string.Format("Duplicate named regions detected: {0}", l.Trim())); 
        } 
        regions[key] = new List<string>(); 
        current_list = regions[key]; 
       } 
       else 
       { 
        if (current_list != null) //ignores code read if it is not within a region 
        { 
         if (l.TrimStart().StartsWith("#endregion", StringComparison.CurrentCultureIgnoreCase)) 
         { 
          current_list = null; //stops using the current list 
         } 
         else 
         { 
          //use current list 
          current_list.Add(l); 
         } 
        } 
       } 
      } 
     } 

     return regions; 
    } 

我希望這可能有所幫助。