`
pandonix
  • 浏览: 401002 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

删除Java代码中的注释

阅读更多

本文的目的在于探讨算法,纯属娱乐和活跃脑细胞。所以,不对删除注释的目的进行讨论:)这是曾经遇到的一道面试题,可惜当时对于题目的理解不到位,导致最后的解法有误。最近有空,静下心来仔细思考了一下,将解法通过BLOG记录下来。

首先,分析一下Java中注释的类型:

/*type1*/

/*
*type2
*/

//type3

 

实际上,type1和type2是同种类型,只是表现上来看,type2中包含了换行符。

最直接的解法,就是记录注释的开始位置,然后等到注释结束时进行删除操作。伪代码如下:

for(输入文本)
  if(/*)记录type1类型注释开始位置;
 else if(//)记录type2注释开始位置;
 else if(*/)根据type1的开始位置,删除注释;
 else if(\n)根据type3的开始位置,删除注释;

看起来问题就这么简单地解决了。然而,我们却没有考虑以下特殊情况:

System.out.println("/*In Mark*/");

代码中的字符串中包含了注释是不能删除的,这下问题有些棘手了。需要判断当前进行删除的注视是否位于字符串之中,所以伪代码修改如下:

for(输入文本)
 if(/*)
      if(引号开始)continue;
      else 记录type1类型注释开始位置;
 else if(//)
      if(引号开始)continue;
      else 记录type3注释开始位置;
 else if(*/)
      根据type1的开始位置,删除注释;
 else if(\n)
      根据type3的开始位置,删除注释;
 else if(")
      if(引号开始)结束引号;
      else 记录引号开始;

 

 完全解决问题了吗?如果引号之中还有一个嵌套的引号,是否会影响对引号开始的判断呢?

 当然,Java中,嵌套引号是需要引入转义符的。所以,在判断引号时,再判断一下是否为转义的引号,如果是,则不进行引号的相关处理。

分析到此为止,下面是实现的代码:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

/**
 * @author Insunny
 * 
 */
public class DelCommentsInJava {

	private static final char MARK = '"';

	private static final char SLASH = '/';

	private static final char BACKSLASH = '\\';

	private static final char STAR = '*';

	private static final char NEWLINE = '\n';
	
	//引号
	private static final int TYPE_MARK = 1;
	
	//斜杠
	private static final int TYPE_SLASH = 2;
	
	//反斜杠
	private static final int TYPE_BACKSLASH = 3;
	
	//星号
	private static final int TYPE_STAR = 4;

	// 双斜杠类型的注释
	private static final int TYPE_DSLASH = 5;

	/**
	 * 删除char[]数组中_start位置到_end位置的元素
	 * 
	 * @param _target
	 * @param _start
	 * @param _end
	 * @return
	 */
	public static char[] del(char[] _target, int _start, int _end) {
		char[] tmp = new char[_target.length - (_end - _start + 1)];
		System.arraycopy(_target, 0, tmp, 0, _start);
		System.arraycopy(_target, _end + 1, tmp, _start, _target.length - _end
				- 1);
		return tmp;
	}

	/**
	 * 删除代码中的注释
	 * 
	 * @param _target
	 * @return
	 */
	public static String delComments(String _target) {
		int preType = 0;
		int mark = -1, cur = -1, token = -1;
		// 输入字符串
		char[] input =  _target.toCharArray();
		for (cur = 0; cur < input.length; cur++) {
			if (input[cur] == MARK) {
				// 首先判断是否为转义引号
				if (preType == TYPE_BACKSLASH)
					continue;
				// 已经进入引号之内
				if (mark > 0) {
					// 引号结束
					mark = -1;
				} else {
					mark = cur;
				}
				preType = TYPE_MARK;
			} else if (input[cur] == SLASH) {
				// 当前位置处于引号之中
				if (mark > 0)
					continue;
				// 如果前一位是*,则进行删除操作
				if (preType == TYPE_STAR) {
					input = del(input, token, cur);
					// 退回一个位置进行处理
					cur = token - 1;
					preType = 0;
				} else if (preType == TYPE_SLASH) {
					token = cur - 1;
					preType = TYPE_DSLASH;
				} else {
					preType = TYPE_SLASH;
				}
			} else if (input[cur] == BACKSLASH) {
				preType = TYPE_BACKSLASH;
			} else if (input[cur] == STAR) {
				// 当前位置处于引号之中
				if (mark > 0)
					continue;
				// 如果前一个位置是/,则记录注释开始的位置
				if (preType == TYPE_SLASH) {
					token = cur - 1;
				}
				preType = TYPE_STAR;
			} else if(input[cur] == NEWLINE)
			{
				if(preType == TYPE_DSLASH)
				{
					input = del(input, token, cur);
					// 退回一个位置进行处理
					cur = token - 1;
					preType = 0;
				}
			}

		}
		return new String(input);
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			File file = new File("./src/Test.java");
			BufferedReader reader = new BufferedReader(new FileReader(file));
			StringBuilder content = new StringBuilder();
			String tmp = null;
			while ((tmp = reader.readLine()) != null) {
				content.append(tmp);
				content.append("\n");
			}
			String target = content.toString();
			System.out.println(delComments(target));
		} catch (Exception e) {

		}
	}

}

 还有别的解决方案吗?能否用正则表达式来实现?继续思考中...

3
0
分享到:
评论
7 楼 shiznet 2012-08-24  
还是有问题的,一个String长度不超过Integer.MAX_VALUE
上述代码对于超长的源码文件可能就不适用了。
6 楼 stillhere 2011-11-30  
好高端的技术、、、
5 楼 zdz8207 2009-06-09  
原来用一句正则表达式就可以完成的
String out = content.replaceAll("\\/\\/[^\\n]*|\\/\\*([^\\*^\\/]*|[\\*^\\/*]*|[^\\**\\/]*)*\\*\\/", "");
4 楼 zdz8207 2009-06-09  
/**
* 创建对象和方法的通用函数,兼容多种浏览器,实现高效、方便的继承体系,解决多种常规创建的性能问题
* @param parantObj jsonObj
* @example
* var Person = coos.Class      //默认派生自object基本类

用楼主的方法只过滤了到前面部分,到“/默认派生自object基本类”这里就不行了。
3 楼 codinglu 2008-07-02  
这个功能其实很好。先关注,以后哪天用的时候,直接来拿
2 楼 pandonix 2008-06-29  
呵呵,多谢楼上的提醒。
直接用char[] input = _target.toCharArray();就可以了。
1 楼 JohnnyJian 2008-06-29  
引用
        char[] input = new char[_target.length()];  
        input = _target.toCharArray();  

居然这样子写……

相关推荐

    使用python脚本删除java文件中的注释

    使用python脚本快速删除java文件中的注释

    清除Java代码注释

    总的来说,清除Java代码注释可以通过多种方式实现,包括使用IDE如MyEclipse的内置功能,编写自定义的注解处理器,或是利用第三方工具。每种方法都有其适用场景,开发者可以根据自身需求和技能水平选择最合适的途径。...

    代码注释删除小工具(java)

    用java编写的代码注释删除小工具,能去文本中掉//和/* */注释。 第一个按钮的功能为去掉文本框1中代码的注释,输出到文本框2. 第二个按钮的功能为批量删除文件中的注释,并输出到当前目录(新文件名为xxx.txt)。但...

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

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

    去除源代码注释

    在编程世界中,源代码注释是极其重要的,它们提供了对程序逻辑的解释,帮助开发者理解和维护代码。然而,在某些特定情况下,如编译优化、代码混淆或仅需执行无注释版本时,可能需要去除源代码中的注释。本文将深入...

    清除java项目中的注释

    在MyEclipse中清除Java代码注释可以通过以下步骤实现: 1.1 打开MyEclipse并导入你的Java项目。 1.2 选择要清理注释的源代码文件或整个项目。你可以通过右键点击项目或文件,然后选择“Refactor” -&gt; “Remove ...

    java_SQL文件批量删除注释

    java_SQL文件批量删除注释 ,实现自动批量处理Sql脚本中的注释,方便发布您自己的脚本,简单好用。亲测可以用的,谢谢支持。

    删除代码中的注释

    这个过程被称为“删除代码中的注释”。下面将详细介绍如何进行这一操作,以及涉及的相关技术。 1. **选择目录**: 在删除代码中的注释时,首先需要确定要处理的代码范围。这通常是一个包含源代码文件的目录。例如...

    java文件注释清除工具

    1.仅支持删除java文件和txt文件;(如果想支持其他格式的文件,请用"."+格式后缀名替换clear_annot类的103行".txt"); 2.仅支持删除以注释开头的行该行前部的注释;(主要是为了删除jd-gui.exe反编译的文件前部的烦人...

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

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

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

    Java是一种广泛使用的编程语言,它的源代码是用Java编写,然后通过编译器转换成字节码(.class..."java-gui-cleaner.jar"简化了这个过程,为开发者提供了一个方便的工具,使他们能够快速地理解和利用已编译的Java代码。

    JAVA代码注释批量删除,及代码格式化

    JAVA代码注释批量删除,及代码格式化。 通过JAVA代码的方式,将项目中所有代码进行批量删除注释内容,包含 // /* */ /** */等。 在删除注释后,统一批量格式化代码,调整代码样式。

    删除源程序中的注释

    2. 遗失信息:注释中可能包含了开发者对某些问题的解决方案、历史变更记录等重要信息,一旦删除可能永久丢失。 3. 法律风险:在开源项目中,删除许可证注释可能违反开源协议,引发法律纠纷。 4. 影响团队协作:...

    Python删除Java源文件中全部注释的实现方法

    在Python脚本中删除Java源文件注释的思路是: 1. 遍历指定目录下的所有`.java`文件。 2. 读取文件内容,并逐字符进行分析。 3. 根据当前的分析状态(初始状态、斜杠状态、块注释状态、行注释状态、字符串状态等),...

    小米便签源代码+注释

    【小米便签源代码+注释】是一款专为学习Java编程和理解软件开发流程的开发者提供的资源。这个压缩包包含了小米便签应用的完整源代码,并且每段代码都有详细的注释,使得初学者能够更好地理解和学习代码的实现逻辑。 ...

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

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

    java删除程序代码的行号

    总结来说,删除Java程序代码的行号主要是为了代码的整洁性和个人偏好,而非对程序运行的影响。在开发环境中,行号对于调试是至关重要的,而在生产环境中,代码的可读性和可维护性更为重要,因此保持良好的代码风格和...

    JavaAPI部分练习代码全注释

    这个压缩包“JavaAPI部分练习代码全注释”显然是为了帮助Java初学者或者有经验的开发者巩固和深化对Java API的理解而准备的。以下是一些关于Java API的重要知识点: 1. **基础类库**:Java API包括了I/O流、集合...

    JAVA实验对源代码进行注释

    在"JAVA实验对源代码进行注释"这个主题中,我们将深入探讨如何有效地使用Java中的不同注释类型,以及它们在软件开发过程中的重要性。 1. 单行注释: Java提供了一种简单的方式来进行单行注释,即使用两个斜线(//...

Global site tag (gtag.js) - Google Analytics