删除java文件中的所有类型的注释

我有一个java项目,我在项目中的各种java文件中的许多位置使用了注释。 现在我需要删除所有类型的注释:单行,多行注释。 请提供自动删除评论。 使用工具或日食等

目前我手动尝试删除所有commet

几个星期前,我不得不写些什么来做这件事。 这应该处理所有注释,嵌套或其他。 它很长,但我还没有看到正确处理嵌套注释的正则表达式版本。 我没有保留javadoc,但我认为你这样做,所以我添加了一些我相信应该处理的代码。 我还添加了代码来支持\ r \ n和\ r \ n行分隔符。 新代码标记为这样。

public static String removeComments(String code) { StringBuilder newCode = new StringBuilder(); try (StringReader sr = new StringReader(code)) { boolean inBlockComment = false; boolean inLineComment = false; boolean out = true; int prev = sr.read(); int cur; for(cur = sr.read(); cur != -1; cur = sr.read()) { if(inBlockComment) { if (prev == '*' && cur == '/') { inBlockComment = false; out = false; } } else if (inLineComment) { if (cur == '\r') { // start untested block sr.mark(1); int next = sr.read(); if (next != '\n') { sr.reset(); } inLineComment = false; out = false; // end untested block } else if (cur == '\n') { inLineComment = false; out = false; } } else { if (prev == '/' && cur == '*') { sr.mark(1); // start untested block int next = sr.read(); if (next != '*') { inBlockComment = true; // tested line (without rest of block) } sr.reset(); // end untested block } else if (prev == '/' && cur == '/') { inLineComment = true; } else if (out){ newCode.append((char)prev); } else { out = true; } } prev = cur; } if (prev != -1 && out && !inLineComment) { newCode.append((char)prev); } } catch (IOException e) { e.printStackTrace(); } return newCode.toString(); } 

您可以通过在项目/文件中搜索以下正则表达式并替换为$1来删除所有单行或多行块注释(但不带//行注释):

^([^"\r\n]*?(?:(?<=')"[^"\r\n]*?|(?

您可能需要多次执行它。

这个正则表达式避免了以下陷阱:

  1. 两条评论之间的代码/* Comment 1 */ foo(); /* Comment 2 */ /* Comment 1 */ foo(); /* Comment 2 */

  2. 以星号开头的//***NOTE***//***NOTE***

  3. 字符串文字内的注释分隔符: stringbuilder.append("/*"); ; 如果在评论之前在单引号内有双引号也是如此

要删除所有单行注释,请在项目/文件中搜索以下正则表达式并替换为$1

^([^"\r\n]*?(?:(?<=')"[^"\r\n]*?|(?

此正则表达式还避免使用双引号内的注释分隔符,但不检查多行注释,因此将错误地删除/* // */

你可以用java-comment-preprocessor来试试:

 java -jar ./jcp-6.0.0.jar --i:/sourceFolder --o:/resultFolder -ef:none --r 

资源

除非您对撰写评论有更多了解,否则处理源代码很难。 在更一般的情况下,您可以在文本常量中使用//或/ *。 所以你真的需要在语法层面解析文件,而不仅仅是词法。 恕我直言,唯一的防弹解决方案是从openjdk的java解析器开始。

如果你知道你的评论从未与代码深深混合(在我的例句中必须是完整的行),python脚本可以帮助

 multiple = False for line in text: stripped = line.strip() if multiple: if stripped.endswith('*/'): multiple = False continue elif stripped.startswith('/*'): multiple = True elif stripped.startswith('//'): pass else: print(line) 

如果您使用的是Eclipse IDE,那么可以让正则表达式为您完成工作。

打开搜索窗口(Ctrl + F),然后选中“正则表达式”。

提供表达式为/ /\*\*(?s:(?!\*/).)*\*/

Prasanth Bhate在Tool中解释了它以删除JavaDoc注释?

这是一个老post,但这可能有助于喜欢像我一样在命令行上工作的人:

下面的perl单行将删除所有评论:

 perl -0pe 's|//.*?\n|\n|g; s#/\*(.|\n)*?\*/##g;' test.java 

例:

 cat test.java this is a test /** *This should be removed *This should be removed */ this should not be removed //this should be removed this should not be removed this should not be removed //this should be removed 

输出:

 perl -0pe 's#/\*\*(.|\n)*?\*/##g; s|//.*?\n|\n|g' test.java this is a test this should not be removed this should not be removed this should not be removed 

如果你想摆脱多个空白行:

 perl -0pe 's|//.*?\n|\n|g; s#/\*(.|\n)*?\*/##g; s/\n\n+/\n\n/g' test.java this is a test this should not be removed this should not be removed this should not be removed 

编辑:纠正正则表达式

我创建了一个开源库并上传到github,它名为CommentRemover,你可以删除单行和多行Java注释。

它支持删除或不删除TODO。
它也支持JavaScript,HTML,CSS,属性,JSP和XML注释。

有一个小代码片段如何使用它(有2种类型用法):

第一种方式是InternalPath

  public static void main(String[] args) throws CommentRemoverException { // root dir is: /Users/user/Projects/MyProject // example for startInternalPath CommentRemover commentRemover = new CommentRemover.CommentRemoverBuilder() .removeJava(true) // Remove Java file Comments.... .removeJavaScript(true) // Remove JavaScript file Comments.... .removeJSP(true) // etc.. goes like that .removeTodos(false) // Do Not Touch Todos (leave them alone) .removeSingleLines(true) // Remove single line type comments .removeMultiLines(true) // Remove multiple type comments .startInternalPath("src.main.app") // Starts from {rootDir}/src/main/app , leave it empty string when you want to start from root dir .setExcludePackages(new String[]{"src.main.java.app.pattern"}) // Refers to {rootDir}/src/main/java/app/pattern and skips this directory .build(); CommentProcessor commentProcessor = new CommentProcessor(commentRemover); commentProcessor.start(); } 

第二种方式ExternalPath

  public static void main(String[] args) throws CommentRemoverException { // example for externalInternalPath CommentRemover commentRemover = new CommentRemover.CommentRemoverBuilder() .removeJava(true) // Remove Java file Comments.... .removeJavaScript(true) // Remove JavaScript file Comments.... .removeJSP(true) // etc.. .removeTodos(true) // Remove todos .removeSingleLines(false) // Do not remove single line type comments .removeMultiLines(true) // Remove multiple type comments .startExternalPath("/Users/user/Projects/MyOtherProject")// Give it full path for external directories .setExcludePackages(new String[]{"src.main.java.model"}) // Refers to /Users/user/Projects/MyOtherProject/src/main/java/model and skips this directory. .build(); CommentProcessor commentProcessor = new CommentProcessor(commentRemover); commentProcessor.start(); } 

这就是我昨天提出的。 这实际上是我从学校得到的作业,所以如果有人在我把它转入之前读到并发现了一个错误,请发表评论=)

PS。 ‘FilterState’是一个枚举类

 public static String deleteComments(String javaCode) { FilterState state = FilterState.IN_CODE; StringBuilder strB = new StringBuilder(); char prevC=' '; for(int i = 0; i 

公共类TestForStrings {

 /** * The main method. * * @param args * the arguments * @throws Exception * the exception */ public static void main(String args[]) throws Exception { String[] imports = new String[100]; String fileName = "Menu.java"; // This will reference one API at a time String line = null; try { FileReader fileReader = new FileReader(fileName); // Always wrap FileReader in BufferedReader. BufferedReader bufferedReader = new BufferedReader(fileReader); int startingOffset = 0; // This will reference one API at a time List lines = Files.readAllLines(Paths.get(fileName), Charset.forName("ISO-8859-1")); // remove single line comments for (int count = 0; count < lines.size(); count++) { String tempString = lines.get(count); lines.set(count, removeSingleLineComment(tempString)); } // remove multiple lines comment for (int count = 0; count < lines.size(); count++) { String tempString = lines.get(count); removeMultipleLineComment(tempString, count, lines); } for (int count = 0; count < lines.size(); count++) { System.out.println(lines.get(count)); } } catch (FileNotFoundException ex) { System.out.println("Unable to open file '" + fileName + "'"); } catch (IOException ex) { System.out.println("Error reading file '" + fileName + "'"); } catch (Exception e) { } } /** * Removes the multiple line comment. * * @param tempString * the temp string * @param count * the count * @param lines * the lines * @return the string */ private static List removeMultipleLineComment(String tempString, int count, List lines) { try { if (tempString.contains("/**") || (tempString.contains("/*"))) { int StartIndex = count; while (!(lines.get(count).contains("*/") || lines.get(count) .contains("**/"))) { count++; } int endIndex = ++count; if (StartIndex != endIndex) { while (StartIndex != endIndex) { lines.set(StartIndex, ""); StartIndex++; } } } } catch (Exception e) { // Do Nothing } return lines; } /** * Remove single line comments . * * @param line * the line * @return the string * @throws Exception * the exception */ private static String removeSingleLineComment(String line) throws Exception { try { if (line.contains(("//"))) { int startIndex = line.indexOf("//"); int endIndex = line.length(); String tempoString = line.substring(startIndex, endIndex); line = line.replace(tempoString, ""); } if ((line.contains("/*") || line.contains("/**")) && (line.contains("**/") || line.contains("*/"))) { int startIndex = line.indexOf("/**"); int endIndex = line.length(); String tempoString = line.substring(startIndex, endIndex); line = line.replace(tempoString, ""); } } catch (Exception e) { // Do Nothing } return line; } 

}