2011-01-22 78 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; 
    } 

我希望这可能有所帮助。