最近一直在搞正则相关的东西,利用空闲时间,改善了下原来项目里比较笨拙的统计代码行数程序。
思路:采用倒推计算的方法,即先删除空行,再删除注释行,每一步之前都统计下剩余的行数,最后再来算 空白行,注释行,和有效代码行。之所以这样考虑有两个原因:一是,多行注释的行数确认比较麻烦,删除后再算可以简化处理。二是JAVA的正则API缺少计数的功能,直接计数肯定要用循环,而且用很多次,比较麻烦。
... 以上为文件读入代码(略)
String separator = "\r\n";
//strFile 为将文件读入字符串
int iCntAll = countMatches(strFile,separator);
//删除空行
strFile = strFile.replaceAll("(?m)^\\s*$"+separator, "");
int iCntNoSpace = countMatches(strFile,separator);
//删除单行注释(注释前有代码的不计)
strFile = strFile.replaceAll("(?m)^\\s*//.*$"+separator, "");
//删除多行注释
//strFile = strFile.replaceAll("(?sm)^\\s*/\\*.*?\\*/\\s*$"+separator, "");
// 10/31修订,在统计一份反编译代码时发现,多行注释后有代码时将发生匹配错误
// 试过几种修补方式未果,改用两次简单的替换来解决
strFile = strFile.replaceAll("(?s)/\\*.*?\\*/", "").replaceAll("(?m)^\\s*$"+separator, "");
int iCntOnlySrc = countMatches(strFile,"\r\n");
int[] linesCnt = new int[3];
//计算空白行 的行数
linesCnt[0] = iCntAll - iCntNoSpace;
//计算注释行 的行数
linesCnt[1] = iCntNoSpace - iCntOnlySrc;
//计算代码行 的行数(总行数-空白行-注释行)
linesCnt[2] = iCntOnlySrc;
... 以下代码略
countMatches()函数:该函数通过统计回车换行的个数来获取行数。
public static int countMatches(CharSequence str, CharSequence sub) {
int count = 0;
int idx = 0;
while ((idx = str.toString().indexOf(sub.toString(), idx)) != -1) {
count++;
idx += sub.length();
}
return count;
}
上面是所有的关键代码,是不是很清爽。稍加修改还可比较容易地适用于其他各种语言的代码统计。
附件中包含完整代码。
10月29日更新:改进了报告格式,增加了总行数/百分比的统计。
试了几个开源库:
spring-framework-3.2.4.RELEASE
空行数 | 注释行数 | 代码行数 |
55293 | 199712 | 197342 |
12% | 44% | 44% |
Google guava common (ver:15.0 不含测试用代码):
空行数 | 注释行数 | 代码行数 |
13881 | 46960 | 65113 |
11% | 37% | 52% |
jodd (ver:3.4.8)
空行数 | 注释行数 | 代码行数 |
17015 | 31728 | 68312 |
15% | 27% | 58% |
看来注释方面 SPRING 的开发者还是更加细致。