2014-04-28 4 views
7

Ich habe ein Java-Projekt und ich habe Kommentare an vielen Orten in verschiedenen Java-Dateien im Projekt verwendet. Jetzt muss ich alle Arten von Kommentaren entfernen: einzelne Zeile, mehrere Zeilen Kommentare. Bitte sorgen Sie für Automatisierung zum Entfernen von Kommentaren. Ich versuche, mit Werkzeugen oder in Eclipse usw.Entfernen aller Arten von Kommentaren in Java-Datei

Aktuell manuell alle commetns

+3

Warum wollen Sie Kommentare entfernen? –

+0

Mögliche Duplikate von: http://stackoverflow.com/questions/9078528/tool-to-remove-javadoc-comments – niiraj874u

+4

Ich muss unseren Client Quellcode geben. Also alle Kommentare aus Quellcode für Clean-Code-Delivarance entfernen. @ Java1, gab es keine Notwendigkeit, meine Frage von geringerer Bedeutung zu machen.Wenn Sie nicht beantworten können als atleast nicht Hürden machen. – haripcce

Antwort

3

ich somehting schreiben musste entfernen diese vor ein paar Wochen zu tun. Dies sollte alle Kommentare, geschachtelt oder anderweitig behandeln. Es ist lang, aber ich habe keine Regex-Version gesehen, die verschachtelte Kommentare richtig behandelt hat. Ich musste Javadoc nicht behalten, aber ich nehme an, dass du das tust, also habe ich Code hinzugefügt, von dem ich glaube, dass er damit umgehen sollte. Ich fügte auch Code hinzu, um die Zeilentrenner \ r \ n und \ r zu unterstützen. Der neue Code ist als solcher gekennzeichnet.

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

Sollte modifizieren, wenn (prev == '/' && cur == '*') zu if ((prev == '/' && cur == '*') || prev == '*' && cur == '*') um Kommentare in Form von/** – JB2

+0

zu unterstützen hat immer noch einen Fehler drin. Wenn ein Kommentar etwas wie '/ * // Hi * /' liest, wird es nicht korrekt entfernt. – BullyWiiPlaza

+0

@BullyWiiPlaza Warum sagst du das? Blockkommentare haben Vorrang vor Zeilenkommentaren im Code, so dass der Kommentar immer noch am */endet. –

1

Der Umgang mit dem Quellcode ist schwierig, es sei denn, Sie wissen mehr über das Schreiben von Kommentaren. Im allgemeineren Fall könnten Sie // oder/* in Textkonstanten haben. Also Ihre wirklich müssen die Datei auf einer Syntaxebene zu analysieren, nicht nur lexikalisch. IMHO wäre die einzige kugelsichere Lösung, zB mit dem Java-Parser von openjdk zu starten.

Wenn Sie wissen, dass Ihre Kommentare mit dem Code nie tief gemischt sind (in meinem exemple kommentiert MUST volle Linien), ein Python-Skript

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) 
+1

** ACHTUNG: das Skript ist bei weitem nicht vollständig und völlig ungetestet. Wie andere sagten, es ist sicherlich eine sehr schlechte Idee, alle Kommentare einschließlich der Urheberrechtshinweise zu entfernen ... –

1

helfen könnte Dies ist eine alte Post, aber dies kann helfen jemand, wie ich auf der Kommandozeile arbeitet gerne:

Die perl Einzeiler unten alle Kommentare entfernen:

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

Beispiel:

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 

Ausgang:

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 

Wenn Sie auch loswerden von mehreren Leerzeilen erhalten möchten:

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: Korrigierte regex

+0

Funktioniert ein Charme und ist schnell! – Mark

1

Wenn Sie verwenden Eclipse IDE, yo Du könntest Regex die Arbeit für dich erledigen lassen.

Öffnen Sie das Suchfenster (Strg + F) und aktivieren Sie "Regulärer Ausdruck".

Geben Sie den Ausdruck als /\*\*(?s:(?!\*/).)*\*/

Prasanth Bhate es in Tool to remove JavaDoc comments?

2

erklärt hat, kann man es versuchen, mit dem Java-Kommentar-Präprozessor:

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

source

+0

Ich habe dieses Projekt ausprobiert. Mir ist aufgefallen, dass wenn ein Java '//' Kommentar entfernt wurde, wenn der Kommentar für die ganze Zeile war (vielleicht mit einigen Leerzeichen oder Tabs davor), er die Zeile nicht entfernt, was schön gewesen wäre .... Ich konnte keine Option dafür finden. Außerdem ist es nicht bekannt, XML/SQL-Kommentare aus XML/SQL-Dateien zu entfernen .... – rapt

0

I machte eine Open Source library und hochgeladen zu github, it Mit dem Namen CommentRemover können Sie Java-Kommentare mit einer oder mehreren Zeilen entfernen.

Es unterstützt entfernen oder NICHT entfernen TODOs.
Es unterstützt auch JavaScript, HTML, CSS, Eigenschaften, JSP und XML Kommentare zu.

Es gibt einen kleinen Code-Schnipsel, wie es zu benutzen (Es gibt 2-Typ-Nutzung):

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

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

Sie alle entfernen Ein- oder mehrzeilige Blockkommentare (aber keine Zeilenkommentare mit //), indem Sie in Ihren Projekt (en)/Datei (en) nach dem folgenden regulären Ausdruck suchen und ihn durch​​ersetzen:

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

Es ist möglich, dass Sie es mehr als einmal auszuführen haben.

Dieser reguläre Ausdruck vermeidet die folgenden Gefahren:

  1. -Code zwischen zwei Kommentare /* Comment 1 */ foo(); /* Comment 2 */

  2. Linie kommentiert mit einem Stern beginnen: //***NOTE***

  3. Kommentarbegrenzer innerhalb Stringliterale: stringbuilder.append("/*");; auch wenn es ein doppeltes Anführungszeichen in einfachen Anführungszeichen vor dem Kommentar ist

alle einzeiligen Kommentare zu entfernen, für den folgenden regulären Ausdruck in Ihrem Projekt suchen (n)/Datei (en) und das Ersetzen von $1:

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

Dieser reguläre Ausdruck auch Kommentarbegrenzer in doppelte Anführungszeichen vermeidet, aber überprüft nicht für mehrzeilige Kommentare, so wird /* // */ falsch entfernt werden.

0

Das ist, was ich gestern erfand. Das sind eigentlich Hausaufgaben, die ich von der Schule bekommen habe. Wenn jemand das liest und einen Fehler findet, bevor ich ihn einschalte, hinterlasse bitte einen Kommentar =)

ps.'FilterState' eine Enum-Klasse

public static String deleteComments(String javaCode) { 
    FilterState state = FilterState.IN_CODE; 

    StringBuilder strB = new StringBuilder(); 

    char prevC=' '; 
    for(int i = 0; i<javaCode.length(); i++){ 
     char c = javaCode.charAt(i); 
     switch(state){ 
      case IN_CODE: 
       if(c=='/') 
        state = FilterState.CAN_BE_COMMENT_START; 
       else { 
        if (c == '"') 
         state = FilterState.INSIDE_STRING; 
        strB.append(c); 
       } 
       break; 
      case CAN_BE_COMMENT_START: 
       if(c=='*'){ 
        state = FilterState.IN_COMMENT_BLOCK; 
       } 
       else if(c=='/'){ 
        state = FilterState.ON_COMMENT_LINE; 
       } 
       else { 
        state = FilterState.IN_CODE; 
        strB.append(prevC+c); 
       } 
       break; 
      case ON_COMMENT_LINE: 
       if(c=='\n' || c=='\r') { 
        state = FilterState.IN_CODE; 
        strB.append(c); 
       } 
       break; 
      case IN_COMMENT_BLOCK: 
       if(c=='*') 
        state=FilterState.CAN_BE_COMMENT_END; 
       break; 
      case CAN_BE_COMMENT_END: 
       if(c=='/') 
        state = FilterState.IN_CODE; 
       else if(c!='*') 
        state = FilterState.IN_COMMENT_BLOCK; 
       break; 
      case INSIDE_STRING: 
       if(c == '"' && prevC!='\\') 
        state = FilterState.IN_CODE; 
       strB.append(c); 
       break; 
      default: 
       System.out.println("unknown case"); 
       return null; 
     } 
     prevC = c; 
    } 
    return strB.toString(); 
} 
0

public class 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<String> 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<String> removeMultipleLineComment(String tempString, 
     int count, List<String> 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; 
} 

}

Verwandte Themen