zoukankan      html  css  js  c++  java
  • 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("关闭文件输入流失败!");
    				}
    			}
    		}
    	}
    }
    测试结果:


  • 相关阅读:
    Atitti 图像处理 图像混合 图像叠加 blend 原理与实现
    Atitit Gaussian Blur 高斯模糊 的原理and实现and 用途
    Atitit 图像处理 灰度图片 灰度化的原理与实现
    Atitit (Sketch Filter)素描滤镜的实现  图像处理  attilax总结
    Atitit 实现java的linq 以及与stream api的比较
    Atitit attilax在自然语言处理领域的成果
    Atitit 图像处理 常用8大滤镜效果 Jhlabs 图像处理类库 java常用图像处理类库
    Atitit 图像处理--图像分类 模式识别 肤色检测识别原理 与attilax的实践总结
    Atitit apache 和guava的反射工具
    atitit。企业的价值观 员工第一 vs 客户第一.docx
  • 原文地址:https://www.cnblogs.com/xyang0917/p/4172519.html
Copyright © 2011-2022 走看看