使用正则表达式计算代码行

时间:2014-06-11 10:01:18

标签: c# regex

我正在编写一个程序来加载项目中的所有.cs文件并计算它们的代码行。

this主题所示,您可以使用以下正则表达式:^~(:Wh@//.+)~(:Wh@{:Wh@)~(:Wh@}:Wh@)~(:Wh@/#).+。然而,这里的问题是它不起作用。我没有收到任何匹配,neither programmatically或通过Visual Studio(2012)中的Search and replace function

在线发现的另一个webpage提供了以下正则表达式:^(?([^\r\n])\s)[^\s+?/]+[^\n]$。这也不会返回预期的代码行。我通过代码指标得到27001,正则表达式返回超过50000。

使用的代码如下。我使用两种方法,一种是获取项目中的所有.cs文件,另一种是实际计算每个.cs文件的行。

private static List < string > GetAllCSFiles(FileInfo projectFile) {
XDocument projectDoc = XDocument.Load(projectFile.FullName);
if (projectDoc.Root == null)
    throw new ArgumentNullException("projectFile");

XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003";
List < XElement > nodes = projectDoc.Descendants(ns + "Compile")
    .Where(x => x.Attribute("Include") != null).ToList();

List < string > csList = nodes.Select(element => element.Attribute("Include").Value).Where(x => x.Contains(".cs")).ToList();
return csList;
}

public static int CalculateLinesOfCode(FileInfo projectFile) {
int lineCount = 0;
string projectLocation = projectFile.DirectoryName;
if (projectLocation == null)
    return -1;

List < string > csList = GetAllCSFiles(projectFile);
const string Pattern = @"^:b*[^:b#/]+.*$";

foreach(string csFile in csList) {
    string fullPath = Path.Combine(projectLocation, csFile);
    FileInfo csFileInfo = new FileInfo(fullPath);
    if (!csFileInfo.Exists)
        continue;

    string[] uncheckedLines = File.ReadAllLines(fullPath);
    foreach(string uncheckedLine in uncheckedLines) {
        if (Regex.IsMatch(uncheckedLine, Pattern))
            lineCount++;
    }
}

return lineCount;
}

上面显示的模式是第二个提供链接的最新模式。

所有项目都按预期加载并读入stringarray,我通过它调试并找到了我的程序所有的行。然而,正则表达式不能按预期工作。

两个问题,如果有人排除了另一个问题

  1. 什么是正确工作的正则表达式来计算代码行?
  2. 是否有另一种(更好?)方式以编程方式计算代码行?

1 个答案:

答案 0 :(得分:0)

首先,我会检查文件新行字符是\r\n(类似于系统的窗口)还是\n(unix like system)。一旦我弄清楚了,我会根据新的行字符分割线条。获得所有行后,只需循环遍历它们并检查该行是否为空。如果它不是空的,那么你有一个代码行。

修改

示例代码

    public static void GetNumberOfCodeLines(string text, out int linesOfCode, out int totalLines)
    {
        linesOfCode = 0;
        totalLines = 0;

        if (string.IsNullOrWhiteSpace(text))
        {
            // there is no code in this text
            return;
        }

        string[] lines = null;

        // test for windows like system new line
        if (text.IndexOf("\r\n") > -1)
        {
            lines = text.Split(new string[] { "\r\n" }, StringSplitOptions.None);
        } // test for unix like systems new line
        else if (text.IndexOf('\n') > -1)
        {
            lines = text.Split(new char[] { '\n' }, StringSplitOptions.None);
        }
        else
        {
            // it's just 1 line of code
            linesOfCode = 1;
            totalLines = 1;
            return;
        }

        foreach(string line in lines)
        {
            totalLines++;

            string lineTest = line.Trim(new char[] { ' ', '\t' });

            if (lineTest.Length > 0 && !lineTest.StartsWith("//") && lineTest != "{" && lineTest != "}" )
            {
                linesOfCode++;
            }
        }
    }