`
zy3381
  • 浏览: 157639 次
  • 性别: 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源代码中的注释,以及涉及的相关知识点。 1. **注释类型** Java中有两种主要的注释方式:单行注释(//)和多行注释(/* ... */)。单行注释从两个斜杠开始,直到行尾结束;多行注释则以...

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

    标题中的"C/C++/Java 源代码注释清除工具"是一个专门针对这三种编程语言设计的实用程序,它的主要功能是移除源代码文件中的注释。在软件开发过程中,注释对于理解和维护代码至关重要,但在特定情况下,如代码混淆、...

    java反编译去除注释一建去除超级简单

    Java是一种广泛使用的编程语言,它的源代码是用Java编写,然后通过编译器转换成字节码(.class文件)来执行。在某些情况下,我们可能需要查看或分析已编译的Java字节码,这时就需要用到反编译工具。本教程将介绍如何...

    清除Java代码注释

    当然,对于非程序员或者希望快速操作的用户,也有一些第三方工具可以实现批量清除Java代码注释,例如Java Comment Remover等。这些工具通常具有用户友好的界面,只需选择目标文件或目录,然后点击“清除注释”按钮...

    去掉代码注释的工具java \ c\c++、php等

    许多集成开发环境(IDEs)如IntelliJ IDEA、Eclipse等也提供了去除代码注释的功能,通常在“重构”或“源代码操作”菜单中可以找到。这种方法方便快捷,但可能不适用于批量处理大量文件。 7. **代码混淆工具** ...

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

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

    清除java项目中的注释

    例如,可以使用maven-java-formatter-plugin或者maven-compiler-plugin的源代码格式化功能,通过配置规则来去除注释。在pom.xml文件中添加相应的插件配置,然后运行相应的Maven命令即可执行注释清理。 3. 关于Java...

    JAVA 去除注释的jar工具

    这个“JAVA 去除注释的jar工具”就是为此目的设计的,它能够帮助开发者从源代码或已编译的jar文件中移除注释。 首先,了解Java注释的种类。Java中的注释主要有三种类型:单行注释(//)、多行注释(/*...*/)和文档...

    原程序注释

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

    java经典去注释程序

    然而,在某些情况下,我们可能需要去除这些注释,例如在处理大量源代码时,或者为了隐私和安全考虑。本项目名为“java经典去注释程序”,专门针对Java代码中的三种主要注释类型——行内注释(//)、块注释(/* */)...

    删除源程序中的注释

    2. 分离源代码和发布版本:将带有注释的源代码作为开发版本保留,发布时使用已去除注释的版本。 3. 文档生成:使用如Doxygen、Javadoc等工具,从源代码生成文档,这样既可以保护源代码的注释,又提供给开发者易于...

    Java源代码混淆器

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

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

    在编程世界中,源代码注释是至关重要的,它们提供了代码功能、逻辑和设计的解释,帮助其他开发者理解和维护代码。然而,在某些情况下,比如编译发布或代码混淆时,可能需要移除这些注释以减小代码体积或增强代码安全...

    java过滤html代码

    在Java编程中,"java过滤html代码"是一个常见的需求,主要目的是为了安全考虑,比如防止XSS(跨站脚本攻击)或者为了提取纯文本内容。这个任务可以通过使用正则表达式来实现,正如描述中提到的那样。下面我们将详细...

    Java 删除项目里面的注释所用到的包.zip

    这个"Java 删除项目里面的注释所用到的包.zip"可能包含了一个或多个工具或库,专门用于自动化删除Java源代码中的注释。在进行这类操作时,需要注意一些关键点以确保代码质量和安全性。 首先,让我们了解一下为什么...

    超详细注释基于BlogJava主页的java爬虫程序

    **超详细注释基于BlogJava主页的Java爬虫程序** 在信息技术领域,网络爬虫是一种自动化获取网页数据的工具,广泛应用于数据挖掘、搜索引擎索引和数据分析等场景。本项目是一个针对BlogJava(一个知名的Java技术交流...

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

    在Java编程领域,注释是源代码中不可或缺的一部分,它们为开发者提供了关于代码功能、用途和实现细节的清晰说明。`ParseJavaFile`项目显然旨在从一个目录中的多个Java源文件中提取这些注释,以便进一步处理和分析。...

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

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

    移除代码注释 软著代码材料

    标题中的“移除代码注释 软著代码材料”指的是在准备软件著作权申请时,可能需要对源代码进行处理,尤其是去除其中的注释部分。这是因为代码注释可能包含敏感信息,比如开发人员的姓名、版权声明或者项目内部的讨论...

    eclipse第二代代码行数、注释行数检查插件

    1. **代码行数统计**:插件能够准确地计算出源代码文件中的实际代码行数,这包括执行逻辑代码,不包含空行和注释。这对于理解项目的工作量、评估开发进度,以及比较不同版本之间的代码变化非常有用。 2. **注释行数...

Global site tag (gtag.js) - Google Analytics