`
zy3381
  • 浏览: 155454 次
  • 性别: Icon_minigender_1
  • 来自: 昆明
社区版块
存档分类
最新评论

Java去除源代码注释

 
阅读更多
总体思路是对待分析的带注释段的字符串进行遍历,声明一个缓冲字符串变量来记录非注释的部分,最后返回这个缓冲字符串变量作为结果

1.首先考虑/*comment*/形式的注释
当遇到/*部分便停止记录,继续往后遍历到*/部分,实现跳过/**/段

2.考虑/*comment/*inside*/out*/形式的嵌套注释
声明一个数字变量来记录/*的开始的次数,遇到一个/*就+1,遇到一个*/就-1,实现嵌套匹配

3.考虑双斜杠注释
发现//形式的字符串的时候表明遇到了双斜杠注释,这时候使用while循环继续向后遍历,直到发现一个换行符,从而跳过整个这一行

4.考虑双引号
双引号中的注释部分是不能去掉的,比如print("//Hello\"World\"/*comment*/");
所以上面几条所考虑的情况都应该是在双引号范围之外,所以应该最先匹配双引号。如果没有出现双引号,则按照上面的规则处理
如果发现了开始双引号,在匹配结束双引号的时候要注意可能会遇到转义双引号,需要跳过以\开始的双引号,从而匹配到正确的结束双引号



import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class main
{

	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		// TODO Auto-generated method stub
		String test1 = "printf(\"Hello /* a comment /* a comment inside comment */ inside /* another comment inside comment */ string */ world\")";
		String test2 = "//*no recursion*/* file header */";
		String test3 = "//*no recursion*/* file header***********/************* Sample input program **********/**************/int spawn_workers(int worker_count) {/* The block below is supposed to spawn 100 workers.     But it creates many more.     Commented until I figure out why  for (int i = 0; i < worker_count; ++i) {    if(!fork()) {      /* This is the worker. Start working. */      do_work();    }  }  */  return 0; /* successfully spawned 100 workers */}int main() {printf(\"Hello /*a comment inside string*/ world\");  int worker_count = 0/*octal number*/144;  if (spawn_workers(worker_count) != 0) {    exit(-1);  }  return 0;}";
		
		String test = ReadFileToString("E:/main.java");
//		System.out.println(removeComments(test));
//		System.out.println(removeCommentsWithQuote(test));
		System.out.println(removeCommentsWithQuoteAndDoubleEscape(test));
	}
/**/
	
	/**
	 * 简单的直接去掉星号斜杠注释段
	 * @param code
	 * @return
	 */
	public static String removeComments(String code)
	{
		StringBuilder sb = new StringBuilder();
		int cnt = 0;
		for (int i = 0; i < code.length(); i++)
		{
			if(cnt == 0)
			{
				if(i+1 < code.length() && code.charAt(i) == '/' && code.charAt(i+1) == '*')
				{
					cnt++;
					i++;
					continue;
				}
			}
			else
			{
				if(i+1 < code.length() && code.charAt(i) == '*' && code.charAt(i+1) == '/')
				{
					cnt--;
					i++;
					continue;
				}
				if(i+1 < code.length() && code.charAt(i) == '/' && code.charAt(i+1) == '*')
				{
					cnt++;
					i++;
					continue;
				}
			}
			if(cnt == 0)
			{
				sb.append(code.charAt(i));
			}
		}
		return sb.toString();
	}
	
	/**
	 * 处理带双引号的注释
	 * @param code
	 * @return
	 */
	public static String removeCommentsWithQuote(String code)
	{
		StringBuilder sb = new StringBuilder();
		int cnt = 0;
		boolean quoteFlag = false;
		for (int i = 0; i < code.length(); i++)
		{
			//如果没有开始双引号范围
			if(!quoteFlag)
			{
				//如果发现双引号开始
				if(code.charAt(i) == '\"')
				{
					sb.append(code.charAt(i));
					quoteFlag = true;
					continue;
				}
				//不在双引号范围内
				else
				{
					//处理/**/注释段
					if(cnt == 0)
					{
						if(i+1 < code.length() && code.charAt(i) == '/' && code.charAt(i+1) == '*')
						{
							cnt++;
							i++;
							continue;
						}
					}
					else
					{
						if(i+1 < code.length() && code.charAt(i) == '*' && code.charAt(i+1) == '/')
						{
							cnt--;
							i++;
							continue;
						}
						if(i+1 < code.length() && code.charAt(i) == '/' && code.charAt(i+1) == '*')
						{
							cnt++;
							i++;
							continue;
						}
					}
					//如果没有发现/**/段或者已经处理完了嵌套的/**/
					if(cnt == 0)
					{
						sb.append(code.charAt(i));
						continue;
					}
				}
			}
			//处理双引号段
			else
			{
				//如果发现双引号结束(非转移形式的双引号)
				if(code.charAt(i) == '\"' && code.charAt(i-1) != '\\')
				{
					sb.append(code.charAt(i));
					quoteFlag = false;
				}
				//双引号开始了但是还没有结束
				else
				{
					sb.append(code.charAt(i));
				}
			}

		}
		return sb.toString();
	}
	
	/**
	 * 处理双引号和双斜杠注释
	 * @param code
	 * @return
	 */
	public static String removeCommentsWithQuoteAndDoubleEscape(String code)
	{
		StringBuilder sb = new StringBuilder();
		int cnt = 0;
		boolean quoteFlag = false;
		for (int i = 0; i < code.length(); i++)
		{
			//如果没有开始双引号范围
			if(!quoteFlag)
			{
				//如果发现双引号开始
				if(code.charAt(i) == '\"')
				{
					sb.append(code.charAt(i));
					quoteFlag = true;
					continue;
				}
				//处理双斜杠注释
				else if(i+1 < code.length() && code.charAt(i) == '/' && code.charAt(i+1) == '/')
				{
					while(code.charAt(i) != '\n')
					{
						i++;
					}
					continue;
				}
				//不在双引号范围内
				else
				{
					//处理/**/注释段
					if(cnt == 0)
					{
						if(i+1 < code.length() && code.charAt(i) == '/' && code.charAt(i+1) == '*')
						{
							cnt++;
							i++;
							continue;
						}
					}
					else
					{
						//发现"*/"结尾
						if(i+1 < code.length() && code.charAt(i) == '*' && code.charAt(i+1) == '/')
						{
							cnt--;
							i++;
							continue;
						}
						//发现"/*"嵌套
						if(i+1 < code.length() && code.charAt(i) == '/' && code.charAt(i+1) == '*')
						{
							cnt++;
							i++;
							continue;
						}
					}
					//如果没有发现/**/注释段或者已经处理完了嵌套的/**/注释段
					if(cnt == 0)
					{
						sb.append(code.charAt(i));
						continue;
					}
				}
			}
			//处理双引号注释段
			else
			{
				//如果发现双引号结束(非转义形式的双引号)
				if(code.charAt(i) == '\"' && code.charAt(i-1) != '\\')
				{
					sb.append(code.charAt(i));
					quoteFlag = false;
				}
				//双引号开始了但是还没有结束
				else
				{
					sb.append(code.charAt(i));
				}
			}
		}
		return sb.toString();
	}
	
	/**
	 * 从一个文件读入到String
	 * @param FilePath
	 * @return
	 */
	public static String ReadFileToString(String FilePath)
	{
		FileInputStream fis = null;
		BufferedReader br = null;
		try
		{
			fis = new FileInputStream(FilePath);
			br = new BufferedReader(new InputStreamReader(fis, "utf-8"));
		} 
		catch (IOException e)
		{
			e.printStackTrace();
		}
		//构建成String
		StringBuffer sb = new StringBuffer();
		String temp = null;
		try
		{
			while((temp = br.readLine()) != null)
			{
				sb.append(temp+'\n');
			}
		} catch (IOException e)
		{
			e.printStackTrace();
		}
		return sb.toString();
	}
}











分享到:
评论

相关推荐

    去除源代码注释

    去除源代码注释,去除java源代码注释.

    C/C++/Java 源代码注释清除工具

    该工具是用于清除C/C++/Java中的// 或/**/的注释。可以对文件夹操作。处理速度非常快。

    java反编译工具以及去掉注释工具

    我们利用jd-gui反编译.classs代码之后,导出来的java源代码里面含有/**,其实这些标记是之前的java源码的注释,我们如何去掉这些标识了?需要利用jd-gui-cleaner.jar工具进行去掉,有需要的可以进行下载使用。 jd-...

    原程序注释

    给定 C/C++ 源程序的源代码,要求去掉所有的注释代码并输出去除注释后的代码。已知 C/C++ 代码的注释有两种:单行注释和多行注释,前者稳以“ // ”引导的行;后者则是由“ /* ”和“ */ ”包含的部分,可以在同一...

    JAVA 去除注释的jar工具

    JAVA 去除注释的jar工具 包括源代码

    Java源代码混淆器

    敏创Java混淆器是广州市敏创信息科技有限公司在保护自己的Java源代码过程中积累的一套实用工具,可以有效地对Java代码进行混淆,达到保护自己知识产权的目的。 工具可以去除空格,回车,注释,有效地减小Java文件...

    去掉java源码注释-CommentRemover:用于从提供的Java源代码中删除注释的源代码

    去掉java源码注释

    java源代码(rt.jar)简洁版(附去注释代码)

    开始学的时候老想搞明白java是怎么实现的,但源代码中注释巨多,烦死人,一直想去掉这些注释,于是学完io后自己动手写了几行代码,终于是去掉了,但唯一不足的是代码不如eclipse中整齐。。。。不管了,现在拿出分享...

    ParseJavaFile:从目录中的源代码中提取注释。 然后

    解析Java文件 通过 ASTParser 从目录中的源代码中提取注释(// 和 /*.../)。 然后: (1)按照命名约定拆分单词(camel) (2)去除停用词。

    java代码-正则去除HTML代码中的注释信息

    java代码-正则去除HTML代码中的注释信息

    代码统计工具(含JAVA源代码)JDK1.6版

    该工具用于统计代码文件大小,更新时间,空白行数,注释行数,实际行数,总行数等相关信息。 该工具利用JDK1.6编写及编译,如使用JDK1.5的JVM请改源文件(SourceCountFrame.java),将文件过滤器去掉即可。或下载1.5...

    各种开发语言注释清理工具

    C++, C#,Java代码批量清理注释工具,支持自定义文件类型清理。

    使用正则去除php代码中的注释方法

    测试代码 文件:a.PHP &lt;?php /** * 加法计算 * 测试 */ // 设定$a的值 $a = 10; // 设定$b的值 $b = 5; // 加法 $c = $a + $b;...echo "去除注释后: ";... * 去除PHP代码注释 * @param string $cont

    Abator加字段注释去多余注释生成UTF-8文件

    去掉原有生成的多余注释,用”__”开头代替原有的“AbatorGenerated_”开头; 增加javabean生成字段...其实代码很简单,可以直接下源代码,在你Abator新增工程目录下修改源代码,然后替换jar下文件,即可实现定制化。

    JAVA版哥们傲剑全脱GUA

    程序全程无注释,不适合JAVA小白.用eclipse neon.2+JDK8开发.如果缺少JAR,run.bat运行时应该有提示,自行度娘,特点是可以在eclipse调试,可同时上百号无压力,不挑电脑.主程序可以用aj.app.autosign.ASP.java调试,相关...

    java的Spring SpringMVC Mybatis框架整合项目源码

    此框架整合的源码是我学习java的spring springMVC mybatis三大框架的时候整合的,源代码附有注释,可读性较强,非常方便研究学习,比较适合跟我一样的初学者,如果需要可下载直接使用,去掉我注释的无关信息即可。

    基于OpenSift和OpenCV的图像拼接,计算机视觉的大作业+源代码+文档说明

    1、资源内容:基于OpenSift和OpenCV的图像拼接,计算机视觉大作业+源代码+文档说明 2、代码特点:内含运行结果,不会运行可私信,参数化编程、参数可方便更改、代码编程思路清晰、注释明细,都经过测试运行成功,...

    Atomineer Pro Documentation Trial 9.32 Cracked

    免责声明:软件仅供技术交流,请勿用于商业及非法用途,如产生法律纠纷与本人无关 AtomineerUtils是国外的一款用于生成源代码注释的一款VS插件,官方网站:http://www.atomineerutils.com/products.php 通过链接,...

    Atomineer Pro Documentation Trial 9.30 Cracked

    AtomineerUtils是国外的一款用于生成源代码注释的一款VS插件,官方网站:http://www.atomineerutils.com/products.php 通过链接,可以看出这款插件的功能十分强大,不像GhostDoc那样,只支持C#,这款插件,支持C、...

    javasrcipt去字符串空格

    JS去字符串空格,在javascript去掉字符串中没用的空格,实用哦,大家不要吝啬您的分数哦!

Global site tag (gtag.js) - Google Analytics