使用go實現(xiàn)刪除sql里面的注釋和字符串功能(demo)
項目里面有一個需求,要對sql進行簡單的語法分析
為了避免sql里面的字符串和注釋對語法分析做干擾,我寫了一個java函數(shù),對sql進行修剪,刪除里面字符串和注釋,用空格代替
周末閑著沒事,我用go重新實現(xiàn)了這個功能,感覺應該會有后來人可以用上
說明:
sql里面的注釋有兩種單行注釋和多行注釋,其中單行注釋以--開頭,以\n結尾,多行注釋以/開頭,以/結尾
sql字符串是以'開頭,'結尾,但特別的地方是連續(xù)兩個單引號是代表一個單引號而不是字符串結束標志
關鍵函數(shù)如下:
` /** 將字節(jié)數(shù)組里面注釋和字符串,用空格替換 rangeBeg和rangeEnd是數(shù)組元素起始位置 左閉右開 */ func TrimSqlByteArray(sql []byte, rangeBeg int, rangeEnd int) []byte { sqlLength := rangeEnd - rangeBeg - 1; //刪除注釋或者字符串后 用空格填充 必免因刪除導致粘連改變sql語義 const chPad = ' ' //結果切片,預分配空間為入?yún)ql長度一半 result := make([] byte, 0, sqlLength / 2) //本字符類型 var charType int = NORMAL; for i := rangeBeg; i < rangeEnd; i++ { /* *utf8編碼不影響判斷 //跳過非英文字符 if sql[i] & 0x80 != 0 { //utf8編碼:UTF-8是一種變長字節(jié)編碼方式。對于某一個字符的UTF-8編碼,如果只有一個字節(jié)則其最高二進制位為0; //如果是多字節(jié),其第一個字節(jié)從最高位開始,連續(xù)的二進制位值為1的個數(shù)決定了其編碼的位數(shù),其余各字節(jié)均以10開頭。 //UTF-8最多可用到6個字節(jié)。 這里不考慮異常,因為go的字符串基本都是標準utf8編碼 i += getPreNotZeroCount(sql[i]) - 1 continue; } */
//本字符類型 預設為普通字符 charType = NORMAL ch := sql[i] //下一個字符 var chNext byte; chNext = getCharSafe(sql, rangeEnd, i + 1) //非有效sql內容結束位置 endPos := 0 if ch == '-' && chNext == '-' { //單行注釋 charType = LINE //下標移到非有效字符的最后 endPos = seekToNext(sql, i + 2, rangeEnd, charType) } else if ch == '/' && chNext == '*' { //多行注釋 charType = MULTI //下標移到非有效字符的最后 endPos = seekToNext(sql, i + 2, rangeEnd, charType) } else if ch == '\'' { //字符串 charType = STRING //下標移到非有效字符的最后 endPos = seekToNext(sql, i + 1, rangeEnd, charType) } //如果字符是非有效字符 則用空格代替 否則保持原樣 if charType == NORMAL { result = append(result, ch) } else { result = append(result, chPad) i = endPos - 1 }
} return result; } /**
獲取字符串或者注釋的右邊界位置(不包含)
rangeEnd是數(shù)組邊界 */ func seekToNext(sql []byte, begPos int, rangeEnd int, charType int) int { result := begPos; switch charType { case MULTI: for ; result < rangeEnd; result++ { ch := sql[result] chNext := getCharSafe(sql, rangeEnd, result+ 1)
if ch == '*' && chNext == '/' { result = result + 1; break; } } break
case LINE: for ; result < rangeEnd; result++ { ch := sql[result]
if ch == '\n' { break; } } break
case STRING: for ; result < rangeEnd; result++ { ch := sql[result] chNext := getCharSafe(sql, rangeEnd, result + 1)
//sql字符串里面連續(xù)的單引號被認為是' 則不是字符串結束標志 if ch == '\'' && chNext == '\'' { result = result + 1; continue; } else if ch == '\'' { break; } } break
default: break; } result++; return result; }
完整代碼及單元測試已上傳 https://github.com/kingstarer/kingstarer.git
到此這篇關于使用go實現(xiàn)刪除sql里面的注釋和字符串功能的文章就介紹到這了,更多相關go刪除sql注釋和字符串內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Go語言利用Unmarshal解析json字符串的實現(xiàn)
本文主要介紹了Go語言利用Unmarshal解析json字符串的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-05-05golang 40行代碼實現(xiàn)通用協(xié)程池
golang協(xié)程機制很方便的解決了并發(fā)編程的問題,但是協(xié)程并不是沒有開銷的,所以也需要適當限制一下數(shù)量。這篇文章主要介紹了golang 40行代碼實現(xiàn)通用協(xié)程池,需要的朋友可以參考下2018-08-08