解析代码文件中的#regions

时间:2011-01-22 05:51:03

标签: c# regex visual-studio-2010 parsing

我正在尝试创建一个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
}
当我指定我正在寻找string时,<。>从* .cs作为Class.Test()

4 个答案:

答案 0 :(得分: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 :(得分:1)

如果您不介意潜在的麻烦问题,那么您只需打开文件并搜索您要查找的关键字即可。

问题来自于这样一个事实,即字符串可能包含您正在查找但不打算搜索的信息。您可以尝试忽略字符串,但由于使用了所有方法(\“,”,等等),这可能会有点复杂。

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

如果你想要做到这一点,那么使用CodeDOM是可行的方法!

答案 2 :(得分:1)

假设我们将整个代码放在字符串类代码中

我们可以这样做

  

string [] regions = Regex.Split(“#region”,classcode);

现在,区域字符串数组将包含您在访问数组时可以访问的区域代码。

你必须从数组中的各个字符串中删除区域名称和#endregion,这不是那么麻烦

答案 3 :(得分: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;
    }

我希望这可能会有所帮助。

相关问题