有時爲了信息保密或是單純閱讀代碼,咱們須要刪除註釋。html
以前考慮過正則表達式,可是感受實現起來至關麻煩。而狀態機能夠把多種狀況歸爲一類狀態再行分解,大大簡化問題。本文就是基於狀態機實現的。java
- 刪除C/C++代碼註釋
- 刪除Java代碼註釋
- 程序
- 參考
思路參考了博客http://www.cnblogs.com/zhanghaiba/p/3569928.html#3853787,寫得很贊。linux
本文基於上面所述博文進行了如下修改或是優化:正則表達式
其中,除狀態NOTE_MULTILINE_STAR外,其他狀態下均需進行字符(串)處理,以保持正確輸出。詳見文末代碼。編程
能夠看到,java中的註釋規則更爲簡單,其中/** */徹底能夠用/* */的狀態涵蓋。且不會出現折行註釋和字符串折行的狀況,所以狀態更加簡單,有興趣的能夠畫一畫,這裏就不畫圖了。換句話說,上面刪除C/C++註釋的程序徹底能夠用來刪除java註釋。windows
1 import java.io.FileInputStream; 2 import java.io.InputStreamReader; 3 import java.io.BufferedReader; 4 5 import java.io.FileOutputStream; 6 import java.io.OutputStreamWriter; 7 import java.io.BufferedWriter; 8 9 import java.io.IOException; 10 11 import java.util.Scanner; 12 13 /** 14 * @author xiaoxi666 15 * @version 1.0.0 2017.12.01 16 */ 17 18 public class deleteCAndCplusplusAndJavaNote { 19 20 /** 21 * 狀態 22 */ 23 enum State { 24 CODE, // 正常代碼 25 SLASH, // 斜槓 26 NOTE_MULTILINE, // 多行註釋 27 NOTE_MULTILINE_STAR, // 多行註釋遇到* 28 NOTE_SINGLELINE, // 單行註釋 29 BACKSLASH, // 折行註釋 30 CODE_CHAR, // 字符 31 CHAR_ESCAPE_SEQUENCE, // 字符中的轉義字符 32 CODE_STRING, // 字符串 33 STRING_ESCAPE_SEQUENCE// 字符串中的轉義字符 34 }; 35 36 /** 37 * @function 刪除代碼中的註釋,以String形式返回 38 * @param strToHandle 待刪除註釋的代碼 39 * @return 已刪除註釋的代碼,String字符串形式 40 */ 41 public static String delete_C_Cplusplus_Java_Note(String strToHandle) { 42 StringBuilder builder = new StringBuilder(); 43 44 State state = State.CODE;// Initiate 45 for (int i = 0; i < strToHandle.length(); ++i) { 46 char c = strToHandle.charAt(i); 47 switch (state) { 48 case CODE: 49 if (c == '/') { 50 state = State.SLASH; 51 }else { 52 builder.append(c); 53 if(c=='\'') { 54 state=State.CODE_CHAR; 55 }else if(c=='\"') { 56 state=State.CODE_STRING; 57 } 58 } 59 break; 60 case SLASH: 61 if (c == '*') { 62 state = State.NOTE_MULTILINE; 63 } else if (c == '/') { 64 state = State.NOTE_SINGLELINE; 65 } else { 66 builder.append('/'); 67 builder.append(c); 68 state = State.CODE; 69 } 70 break; 71 case NOTE_MULTILINE: 72 if(c=='*') { 73 state=State.NOTE_MULTILINE_STAR; 74 }else { 75 if(c=='\n') { 76 builder.append("\r\n");//保留空行,固然,也能夠去掉 77 } 78 state=State.NOTE_MULTILINE;//保持當前狀態 79 } 80 break; 81 case NOTE_MULTILINE_STAR: 82 if(c=='/') { 83 state=State.CODE; 84 }else if(c=='*') { 85 state=State.NOTE_MULTILINE_STAR;//保持當前狀態 86 } 87 else { 88 state=State.NOTE_MULTILINE; 89 } 90 break; 91 case NOTE_SINGLELINE: 92 if(c=='\\') { 93 state=State.BACKSLASH; 94 }else if(c=='\n'){ 95 builder.append("\r\n"); 96 state=State.CODE; 97 }else { 98 state=State.NOTE_SINGLELINE;//保持當前狀態 99 } 100 break; 101 case BACKSLASH: 102 if(c=='\\' || c=='\r'||c=='\n') {//windows系統換行符爲\r\n 103 if(c=='\n') { 104 builder.append("\r\n");//保留空行,固然,也能夠去掉 105 } 106 state=State.BACKSLASH;//保持當前狀態 107 }else { 108 state=State.NOTE_SINGLELINE; 109 } 110 break; 111 case CODE_CHAR: 112 builder.append(c); 113 if(c=='\\') { 114 state=State.CHAR_ESCAPE_SEQUENCE; 115 }else if(c=='\'') { 116 state=State.CODE; 117 }else { 118 state=State.CODE_CHAR;//保持當前狀態 119 } 120 break; 121 case CHAR_ESCAPE_SEQUENCE: 122 builder.append(c); 123 state=State.CODE_CHAR; 124 break; 125 case CODE_STRING: 126 builder.append(c); 127 if(c=='\\') { 128 state=State.STRING_ESCAPE_SEQUENCE; 129 }else if(c=='\"') { 130 state=State.CODE; 131 }else { 132 state=State.CODE_STRING;//保持當前狀態 133 } 134 break; 135 case STRING_ESCAPE_SEQUENCE: 136 builder.append(c); 137 state=State.CODE_STRING; 138 break; 139 default: 140 break; 141 } 142 } 143 return builder.toString(); 144 } 145 146 /** 147 * @function 從指定文件中讀取代碼內容,以String形式返回 148 * @param inputFileName 待刪除註釋的文件 149 * @return 待刪除註釋的文件中的代碼內容,String字符串形式 150 * @note 輸入文件格式默認爲 UTF-8 151 */ 152 public static String readFile(String inputFileName) { 153 StringBuilder builder = new StringBuilder(); 154 try { 155 FileInputStream fis = new FileInputStream(inputFileName); 156 InputStreamReader dis = new InputStreamReader(fis); 157 BufferedReader reader = new BufferedReader(dis); 158 String s; 159 // 每次讀取一行,當改行爲空時結束 160 while ((s = reader.readLine()) != null) { 161 builder.append(s); 162 builder.append("\r\n");// windows系統換行符 163 } 164 reader.close(); 165 dis.close(); 166 fis.close(); 167 } catch (IOException e) { 168 e.printStackTrace(); 169 System.exit(1); 170 } 171 return builder.toString(); 172 } 173 174 /** 175 * @function 將刪除註釋後的代碼保存到指定新文件 176 * @param outputFileName 保存「刪除註釋後的代碼」的文件的文件名 177 * @param strHandled 刪除註釋後的代碼 178 */ 179 public static void writeFile(String outputFileName, String strHandled) { 180 try { 181 FileOutputStream fos = new FileOutputStream(outputFileName); 182 OutputStreamWriter dos = new OutputStreamWriter(fos); 183 BufferedWriter writer = new BufferedWriter(dos); 184 writer.write(strHandled); 185 writer.close(); 186 dos.close(); 187 fos.close(); 188 System.out.println("code that without note has been saved successfully in " + outputFileName); 189 } catch (IOException e) { 190 e.printStackTrace(); 191 } 192 } 193 194 /** 195 * @function 讀取待處理文件,刪除註釋,處理過的代碼寫入新文件 196 * @param args 197 */ 198 public static void main(String[] args) { 199 Scanner in = new Scanner(System.in); 200 //待刪除註釋的文件 201 System.out.println("The fileName that will be delete note:"); 202 String inputFileName = in.nextLine(); 203 //保存「刪除註釋後的代碼」的文件 204 System.out.println("The fileName that will save code without note:"); 205 String outputFileName = in.nextLine(); 206 207 String strToHandle = readFile(inputFileName); 208 String strHandled = delete_C_Cplusplus_Java_Note(strToHandle); 209 writeFile(outputFileName, strHandled); 210 211 } 212 213 }
- 怎樣刪除C/C++代碼中的全部註釋?淺談狀態機的編程思想: http://www.cnblogs.com/zhanghaiba/p/3569928.html#3853787
- 誰能寫出個刪除註釋的正則表達式:http://bbs.csdn.net/topics/380183706
- 正則表達式刪除代碼的註釋: http://blog.csdn.net/conquer0715/article/details/14446463