898
技術社區[雲棲]
Java正則表達式(三)、代碼量統計工具(統計java源文件中注釋、代碼、空白行數量)
比如想統計一個Java程序員一天寫代碼的工作量(如:有效代碼多少行、空行多少、注釋多少行等),這個小工具也許能做為一個參考的依據。
思路:因為每個java源文件的內容基本包括java語句、空白行、注釋三部份組成(不包括注解),所以要統計某個文件這三部份的內容各占多少時,隻需寫三個匹配這幾部份內容的正則表達式即可。然後通過IO流讀取文件中的每一行,並根據正則匹配的結果,累加每部份匹配的數量即可。
注釋行:單行注釋(//)、多行注釋、文檔注釋。正則:((//)|(/\\*+)|((^\\s)*\\*)|((^\\s)*\\*+/))+
空白行:一行內隻有空格、\t、\n等非可視字符表示空白行。正則:^\\s*$
代碼行:以分號“;“結束為一行有效的代碼。正則:(?!import|package).+;\\s*(((//)|(/\\*+)).*)*
實現方式:
1、用戶在控製台輸入要統計的java文件路徑或目錄
2、根據路徑創建一個File對象,判斷文件是否有效,並給出提示。最後將文件和IO流綁定
3、循環讀取文件中的某一行,並根據正則匹配的結果累記每部份匹配的數量
完整代碼如下:
package regex; import java.io.BufferedReader; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.util.Scanner; import java.util.regex.Pattern; /** * 代碼統計工具 * 統計某個java源文件或某個目錄中所有java源文件中注釋、空白行、代碼行各占多少行 * 注釋:包括單行注釋(//)、多行注釋、文檔注釋 * 空白行:一行內沒有任何內容的表示空白行 * 代碼行:以分號“;”結束的一條語句,可以統計為一行有效代碼 */ public class CodeStatDemo { // 記錄注釋行數 static long annotationLine = 0; // 記錄空白行數 static long blankLine = 0; // 記錄有效代碼的行數 static long codeLine = 0; // 代碼總行數 static long totalLine = 0; // 文件總數 static long fileCount = 0; public static void main(String[] args) throws FileNotFoundException { System.out.println("請輸入要統計代碼量的java文件或java目錄:"); Scanner in = new Scanner(System.in); String filePath = in.nextLine(); File file = new File(filePath); // 根據用戶輸入的文件名和目錄執行代碼量統計 codeStat(file); System.out.println("----------統計結果---------"); System.out.println("文件數量:" + fileCount + "個"); System.out.println(file + "文件/目錄總行數:" + totalLine); System.out.println("代碼行數:" + codeLine); System.out.println("注釋行數:" + annotationLine); System.out.println("空白行數:" + blankLine); long otherLine = totalLine - (codeLine + annotationLine + blankLine); System.out.println("其它行數:" + otherLine); } private static void codeStat(File file) throws FileNotFoundException { if (file == null || !file.exists()) throw new FileNotFoundException(file + ",文件不存在!"); fileCount ++; // 文件數累加 if (file.isDirectory()) { File[] files = file.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { return pathname.getName().endsWith(".java") || pathname.isDirectory(); } }); for (File target : files) { codeStat(target); } } else { BufferedReader bufr = null; try { // 將指定路徑的文件與字符流綁定 bufr = new BufferedReader(new InputStreamReader(new FileInputStream(file))); } catch (FileNotFoundException e) { throw new FileNotFoundException(file + ",文件不存在!" + e); } // 定義匹配每一行的正則匹配器 Pattern annotationLinePattern = Pattern.compile("((//)|(/\\*+)|((^\\s)*\\*)|((^\\s)*\\*+/))+", Pattern.MULTILINE + Pattern.DOTALL); // 注釋匹配器(匹配單行、多行、文檔注釋) Pattern blankLinePattern = Pattern.compile("^\\s*$"); // 空白行匹配器(匹配回車、tab鍵、空格) Pattern codeLinePattern = Pattern.compile("(?!import|package).+;\\s*(((//)|(/\\*+)).*)*", Pattern.MULTILINE + Pattern.DOTALL); // 代碼行匹配器(以分號結束為一行有效語句,但不包括import和package語句) // 遍曆文件中的每一行,並根據正則匹配的結果記錄每一行匹配的結果 String line = null; try { while((line = bufr.readLine()) != null) { if (annotationLinePattern.matcher(line).find()) { annotationLine ++; } if (blankLinePattern.matcher(line).find()) { blankLine ++; } if (codeLinePattern.matcher(line).matches()) { codeLine ++; } totalLine ++; } } catch (IOException e) { throw new RuntimeException("讀取文件失敗!" + e); } finally { try { bufr.close(); // 關閉文件輸入流並釋放係統資源 } catch (IOException e) { throw new RuntimeException("關閉文件輸入流失敗!"); } } } } }測試結果:

最後更新:2017-04-02 16:47:46