状态机编程思想:删除代码注释(支持C/C++和Java)
生活随笔
收集整理的這篇文章主要介紹了
状态机编程思想:删除代码注释(支持C/C++和Java)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
前言
有時為了信息保密或是單純閱讀代碼,我們需要刪除注釋。
之前考慮過正則表達(dá)式,但是感覺實現(xiàn)起來相當(dāng)麻煩。而狀態(tài)機可以把多種情況歸為一類狀態(tài)再行分解,大大簡化問題。本文就是基于狀態(tài)機實現(xiàn)的。
刪除C/C++代碼注釋
需要考慮的情況
- //
- /* */
- //和/* */嵌套(注意不存在/* */和/* */嵌套)
- 折行注釋(用\間隔)
- 字符中存在的/和*
- 字符串中存在的//和/* */
- 字符串中的折行代碼(用\間隔)
- 頭文件中可能存在的/
- 狀態(tài)轉(zhuǎn)移描述
狀態(tài)轉(zhuǎn)移描述
思路參考了博客怎樣刪除C/C++代碼中的所有注釋?淺談狀態(tài)機的編程思想,寫得很贊。
本文基于上面所述博文進(jìn)行了以下修改或是優(yōu)化:
- 原博文沒有考慮/***/的情況(其中*的個數(shù)為奇數(shù)),已修正
- 切換到了windows平臺下,支持windows換行\(zhòng)r\n(并請注意:如果原文件末尾沒有回車,會自動插入)
- 狀態(tài)量優(yōu)化為枚舉常量
- 狀態(tài)轉(zhuǎn)移由if...else...elseif結(jié)構(gòu)改為switch...case結(jié)構(gòu),更為清晰,對于大型代碼,效率更高
其中,除狀態(tài)NOTE_MULTILINE_STAR外,其余狀態(tài)下均需進(jìn)行字符(串)處理,以保持正確輸出。詳見文末代碼。
刪除Java代碼注釋
需要考慮的情況
- //
- /* */
- /** */
- //和/**/嵌套(注意不存在/* */和/* */嵌套,不存在/** */和/** */嵌套,不存在/* */和/** */嵌套)
- //和/** */嵌套
- 字符中存在的/和*
- 字符串中存在的//、/**/以及/** */
- 狀態(tài)轉(zhuǎn)移描述
狀態(tài)轉(zhuǎn)移描述
可以看到,java中的注釋規(guī)則更為簡單,其中/** */完全可以用/* */的狀態(tài)涵蓋。且不會出現(xiàn)折行注釋和字符串折行的情況,因此狀態(tài)更加簡單,有興趣的可以畫一畫,這里就不畫圖了。換句話說,上面刪除C/C++注釋的程序完全可以用來刪除java注釋。
程序
package code_tools;import java.io.FileInputStream; import java.io.InputStreamReader; import java.io.BufferedReader;import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.BufferedWriter;import java.io.IOException;import java.util.Scanner;/*** @author xiaoxi666* @version 1.0.0 2017.12.01*/public class deleteCAndCplusplusAndJavaNote {/*** 狀態(tài)*/enum State {CODE, // 正常代碼SLASH, // 斜杠NOTE_MULTILINE, // 多行注釋NOTE_MULTILINE_STAR, // 多行注釋遇到*NOTE_SINGLELINE, // 單行注釋BACKSLASH, // 折行注釋CODE_CHAR, // 字符CHAR_ESCAPE_SEQUENCE, // 字符中的轉(zhuǎn)義字符CODE_STRING, // 字符串STRING_ESCAPE_SEQUENCE// 字符串中的轉(zhuǎn)義字符};/*** @function 刪除代碼中的注釋,以String形式返回* @param strToHandle 待刪除注釋的代碼* @return 已刪除注釋的代碼,String字符串形式*/public static String delete_C_Cplusplus_Java_Note(String strToHandle) {StringBuilder builder = new StringBuilder();State state = State.CODE;// Initiatefor (int i = 0; i < strToHandle.length(); ++i) {char c = strToHandle.charAt(i);switch (state) {case CODE:if (c == '/') {state = State.SLASH;}else {builder.append(c);if(c=='\'') {state=State.CODE_CHAR;}else if(c=='\"') {state=State.CODE_STRING;}} break;case SLASH:if (c == '*') {state = State.NOTE_MULTILINE;} else if (c == '/') {state = State.NOTE_SINGLELINE;} else {builder.append('/');builder.append(c);state = State.CODE;}break;case NOTE_MULTILINE:if(c=='*') {state=State.NOTE_MULTILINE_STAR;}else {if(c=='\n') {builder.append("\r\n");//保留空行,當(dāng)然,也可以去掉}state=State.NOTE_MULTILINE;//保持當(dāng)前狀態(tài)}break;case NOTE_MULTILINE_STAR:if(c=='/') {state=State.CODE;}else if(c=='*') {state=State.NOTE_MULTILINE_STAR;//保持當(dāng)前狀態(tài)}else {state=State.NOTE_MULTILINE;}break;case NOTE_SINGLELINE:if(c=='\\') {state=State.BACKSLASH;}else if(c=='\n'){builder.append("\r\n");state=State.CODE;}else {state=State.NOTE_SINGLELINE;//保持當(dāng)前狀態(tài)}break;case BACKSLASH:if(c=='\\' || c=='\r'||c=='\n') {//windows系統(tǒng)換行符為\r\nif(c=='\n') {builder.append("\r\n");//保留空行,當(dāng)然,也可以去掉}state=State.BACKSLASH;//保持當(dāng)前狀態(tài)}else {state=State.NOTE_SINGLELINE;}break;case CODE_CHAR:builder.append(c);if(c=='\\') {state=State.CHAR_ESCAPE_SEQUENCE;}else if(c=='\'') { state=State.CODE;}else {state=State.CODE_CHAR;//保持當(dāng)前狀態(tài)}break;case CHAR_ESCAPE_SEQUENCE:builder.append(c);state=State.CODE_CHAR;break;case CODE_STRING:builder.append(c);if(c=='\\') {state=State.STRING_ESCAPE_SEQUENCE;}else if(c=='\"') { state=State.CODE;}else {state=State.CODE_STRING;//保持當(dāng)前狀態(tài)}break;case STRING_ESCAPE_SEQUENCE:builder.append(c);state=State.CODE_STRING;break;default:break;}}return builder.toString();}/*** @function 從指定文件中讀取代碼內(nèi)容,以String形式返回* @param inputFileName 待刪除注釋的文件* @return 待刪除注釋的文件中的代碼內(nèi)容,String字符串形式* @note 輸入文件格式默認(rèn)為 UTF-8*/public static String readFile(String inputFileName) {StringBuilder builder = new StringBuilder();try {FileInputStream fis = new FileInputStream(inputFileName);InputStreamReader dis = new InputStreamReader(fis);BufferedReader reader = new BufferedReader(dis);String s;// 每次讀取一行,當(dāng)改行為空時結(jié)束while ((s = reader.readLine()) != null) {builder.append(s);builder.append("\r\n");// windows系統(tǒng)換行符}reader.close();dis.close();fis.close();} catch (IOException e) {e.printStackTrace();System.exit(1);}return builder.toString();}/*** @function 將刪除注釋后的代碼保存到指定新文件* @param outputFileName 保存“刪除注釋后的代碼”的文件的文件名* @param strHandled 刪除注釋后的代碼*/public static void writeFile(String outputFileName, String strHandled) {try {FileOutputStream fos = new FileOutputStream(outputFileName);OutputStreamWriter dos = new OutputStreamWriter(fos);BufferedWriter writer = new BufferedWriter(dos);writer.write(strHandled);writer.close();dos.close();fos.close();System.out.println("code that without note has been saved successfully in " + outputFileName);} catch (IOException e) {e.printStackTrace();}}/*** @function 讀取待處理文件,刪除注釋,處理過的代碼寫入新文件* @param args*/public static void main(String[] args) {Scanner in = new Scanner(System.in);//待刪除注釋的文件System.out.println("The fileName that will be delete note:");String inputFileName = in.nextLine();//保存“刪除注釋后的代碼”的文件System.out.println("The fileName that will save code without note:");String outputFileName = in.nextLine();String strToHandle = readFile(inputFileName);String strHandled = delete_C_Cplusplus_Java_Note(strToHandle);writeFile(outputFileName, strHandled);}}復(fù)制代碼說明
- 本程序保留注釋占用行,也就是說,注釋以外的代碼原樣保留(行數(shù)也不會變),注釋行變?yōu)榭瞻住?/li>
- 不檢測文件后綴(這就意味著把代碼寫在.txt里面也可以處理),有需求的可以自行添加。
- 本程序適用于windows平臺,其他平臺如linux和mac請?zhí)鎿Q“\r\n”換行符。文件格式默認(rèn)為UTF。
- 有興趣的可以封裝成圖形界面,直接拖入文件處理,更好用。
- 本程序經(jīng)過大量測試未發(fā)現(xiàn)bug,若讀者發(fā)現(xiàn)bug,歡迎提出。
參考
- 怎樣刪除C/C++代碼中的所有注釋?淺談狀態(tài)機的編程思想
- 誰能寫出個刪除注釋的正則表達(dá)式
- 正則表達(dá)式刪除代碼的注釋
總結(jié)
以上是生活随笔為你收集整理的状态机编程思想:删除代码注释(支持C/C++和Java)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle 11g忘记SYS和SYST
- 下一篇: s3c2440移植MQTT