2014-04-28 13 views
7

Mam projekt java i użyłem komentarzy w wielu lokalizacjach w różnych plikach Java w projekcie. Teraz muszę usunąć wszystkie typy komentarzy: pojedynczą, wielowierszową. Proszę podać automatyzację usuwania komentarzy. za pomocą narzędzi lub w zaćmienie itpUsuwanie wszystkich typów komentarzy w pliku Javy

Obecnie jestem ręcznie próbuje usunąć wszystkie commetns

+3

Dlaczego chcesz usunąć komentarz? –

+0

Możliwe duplikaty: http://stackoverflow.com/questions/9078528/tool-to-remove-javadoc-comments – niiraj874u

+4

Potrzebuję podać kod źródłowy do naszego klienta. W związku z tym usunięcie wszystkich komentarzy z kodu źródłowego dla czystego dostarczania kodu. @ Java1, nie było potrzeby, aby moje pytanie o mniejszej ważności. Jeśli nie możesz odpowiedzieć, to przynajmniej nie rób przeszkód. – haripcce

Odpowiedz

3

miałem napisać somehting zrobić to kilka tygodni temu. Powinno to obsłużyć wszystkie komentarze, zagnieżdżone lub w inny sposób. Jest długi, ale nie widziałem wersji regex, która poprawnie obsłużyła komentarze zagnieżdżone. Nie musiałem zachowywać javadoc, ale przypuszczam, że tak, więc dodałem kod, który powinienem sobie z tym poradzić. Dodałem również kod obsługujący separatory linii \ r \ n i \ r. Nowy kod jest oznaczony jako taki.

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

Należy zmodyfikować, jeśli (prev == '/ && cur == '*') to if ((poprzednia == '/' && cur == '' ') || prev ==' * '&& cur ==' * ') w celu obsługi komentarzy w formie/** – JB2

+0

nadal tam jest błąd. Jeśli komentarz czyta coś w rodzaju '/ * // Hi * /', nie zostanie poprawnie usunięty – BullyWiiPlaza

+0

@BullyWiiPlaza Dlaczego tak mówisz? Komentarze blokowe mają precedens w stosunku do komentarzy liniowych w kodzie, więc nadal będą kończyły komentarz w * /. –

1

Radzenie sobie z kodem źródłowym jest trudne, chyba że wiesz więcej na temat pisania komentarza. W bardziej ogólnym przypadku możesz mieć // lub/* w stałych tekstowych. Tak więc Twój naprawdę trzeba przeanalizować plik na poziomie składni, nie tylko leksykalny. IMHO jedynym rozwiązaniem kuloodpornym byłoby uruchomienie na przykład parsera java z openjdk.

Jeśli wiesz, że komentarze nie są głęboko mieszany z kodem (w moim exemple komentuje MUST być kompletne linie), skrypt python mógł pomóc

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

** UWAGA **: scenariusz jest daleki od ukończenia i całkowicie nieprzetestowany. Jak powiedzieli inni, z pewnością jest to ** bardzo zły ** pomysł, aby usunąć wszystkie komentarze, w tym informacje o prawach autorskich ... –

1

Jest to stary post, ale może to pomóc komuś, kto lubi pracować na linii poleceń jak ja:

perl jedno-liner poniżej usunie wszystkie komentarze:

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

Przykład:

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 

wyjściowa:

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 

Jeśli chcesz pozbyć się wielu pustych wierszy, a także:

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

+0

Działa urok i jest szybki! – Mark

1

Jeśli używasz Eclipse IDE, yo możesz zrobić regex, wykonując pracę za ciebie.

Otwórz okno wyszukiwania (Ctrl + F) i zaznacz "Wyrażenie regularne".

Podaj wyrażenie jako /\*\*(?s:(?!\*/).)*\*/

Prasanth Bhate wyjaśnił to w Tool to remove JavaDoc comments?

2

można spróbować go z java-comment-preprocesora:

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

source

+0

Próbowałem tego projektu. Zauważyłem, że po usunięciu komentarza Java '//', jeśli komentarz dotyczył całej linii (może z białymi spacjami lub zakładkami przed nią), to nie usuwa linii, która byłaby miła .... Nie mogłem znaleźć takiej opcji. Ponadto nie wie, aby usunąć (XML/SQL) komentarze z plików XML/SQL .... – rapt

0

I zrobione open source library i przesłane do github, to s o nazwie CommentRemover możesz usunąć pojedyncze i wiele linii komentarzy Java.

Obsługuje usuwanie lub NIE usuwa TODO.
Obsługuje również skrypty JavaScript, HTML, CSS, właściwości, komentarze JSP i XML.

Jest trochę kod snippet jak go używać (Jest 2 Wykorzystanie typ):

Pierwszy sposób 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();   
    } 

Drugi sposób 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

Można usunąć wszystkie komentarze do bloku jedno- lub wielowierszowego (ale nie do komentarzy liniowych z //) poprzez wyszukanie następującego wyrażenia regularnego w projekcie/projektach/plikach i zastąpienie przez $1:

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

Jest możliwe, że trzeba ją wykonać więcej niż jeden raz.

To wyrażenie regularne unika następujące pułapek:

  1. Code między dwa komentarze /* Comment 1 */ foo(); /* Comment 2 */

  2. Linia komentuje wychodząc z gwiazdką: //***NOTE***

  3. komentarz ograniczniki wewnątrz napisowych: stringbuilder.append("/*");; także jeśli jest podwójny cudzysłów wewnątrz apostrofów przed komentarzem

Aby usunąć wszystkie komentarze pojedynczej linii, wyszukiwanie poniższego wyrażenia regularnego w projekcie (ów)/file (s) i zastąpienie przez $1:

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

To wyrażenie regularne unika również ograniczniki komentarz wewnątrz podwójnych cudzysłowów, ale nie sprawdza komentarze multi-line, więc /* // */ zostanie niepoprawnie usunięty.

0

Oto, co wymyśliłem wczoraj. To jest praca domowa, którą dostałem ze szkoły, więc jeśli ktokolwiek to przeczyta i znajdzie błąd zanim go włączę, proszę zostaw komentarz =)

ps.'FilterState' to klasa ENUM

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

klasy TestForStrings publiczne {

/** 
* 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; 
} 

}

Powiązane problemy