Removing all types of comments in java file

24,470

Solution 1

You can remove all single- or multi-line block comments (but not line comments with //) by searching for the following regular expression in your project(s)/file(s) and replacing by $1:

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

It's possible that you have to execute it more than once.

This regular expression avoids the following pitfalls:

  1. Code between two comments /* Comment 1 */ foo(); /* Comment 2 */

  2. Line comments starting with an asterisk: //***NOTE***

  3. Comment delimiters inside string literals: stringbuilder.append("/*");; also if there is a double quote inside single quotes before the comment

To remove all single-line comments, search for the following regular expression in your project(s)/file(s) and replace by $1:

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

This regular expression also avoids comment delimiters inside double quotes, but does NOT check for multi-line comments, so /* // */ will be incorrectly removed.

Solution 2

I had to write somehting to do this a few weeks ago. This should handle all comments, nested or otherwise. It is long, but I haven't seen a regex version that handled nested comments properly. I didn't have to preserve javadoc, but I presume you do, so I added some code that I belive should handle that. I also added code to support the \r\n and \r line separators. The new code is marked as such.

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();
}

Solution 3

This is an old post but this may help someone who enjoys working on command line like myself:

The perl one-liner below will remove all comments:

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

Example:

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

Output:

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 

If you want get rid of multiple blank lines as well:

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 

EDIT: Corrected regex

Solution 4

you can try it with the java-comment-preprocessor:

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

source

Solution 5

I made a open source library and uploaded to github, its called CommentRemover you can remove single line and multiple line Java Comments.

It supports remove or NOT remove TODO's.
Also it supports JavaScript , HTML , CSS , Properties , JSP and XML Comments too.

There is a little code snippet how to use it (There is 2 type usage):

First way 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();        
  }

Second way 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();        
  }
Share:
24,470
haripcce
Author by

haripcce

Updated on July 09, 2022

Comments

  • haripcce
    haripcce almost 2 years

    I have a java project and i have used comments in many location in various java files in the project. Now i need to remove all type of comments : single line , multiple line comments . Please provide automation for removing comments. using tools or in eclipse etc.

    Currently i am manually trying to remove all commetns

  • Serge Ballesta
    Serge Ballesta about 10 years
    BEWARE : the script is far from complete and totally untested. As others said, it is certainly a very bad idea to remove all comments including copyright notices ...
  • JB2
    JB2 over 9 years
    Should modify if (prev == '/' && cur == '') to if ((prev == '/' && cur == '') || prev == '' && cur == '') to support comments in the form of /**
  • BullyWiiPlaza
    BullyWiiPlaza about 8 years
    You still got a bug in there. If a comment read something like /*// Hi */ it will not be removed properly
  • Andrew Vitkus
    Andrew Vitkus about 8 years
    @BullyWiiPlaza Why do you say that? Block comments have precedent over line comments in the code so it will still end the comment at the */.
  • BullyWiiPlaza
    BullyWiiPlaza about 8 years
    @AndrewVitkus I applied it to a big source code and it didn't work correctly for those cases apparently, that's all
  • arun-r
    arun-r over 7 years
    It doesn't work if comments are in this format /** /, I replaced all /* to /* in string before calling this proc
  • Mark
    Mark about 7 years
    Works a charm and is quick!
  • rapt
    rapt over 6 years
    I have tried this project. I noticed that once it removes a Java // comment, if the comment was for the whole line (maybe with some white spaces or tabs before it), it does not remove the line, which would have been nice.... I could not find an option for this. Also, it does not know to remove (XML/SQL) comments from XML/SQL files....
  • Dan Tanner
    Dan Tanner about 2 years
    This would replace https://example.com with https: