我正在编写一个程序来加载项目中的所有.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,我通过它调试并找到了我的程序所有的行。然而,正则表达式不能按预期工作。
两个问题,如果有人排除了另一个问题
答案 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++;
}
}
}