使⽤go实现删除sql⾥⾯的注释和字符串功能(demo)项⽬⾥⾯有⼀个需求,要对sql进⾏简单的语法分析
为了避免sql⾥⾯的字符串和注释对语法分析做⼲扰,我写了⼀个java函数,对sql进⾏修剪,删除⾥⾯字符串和注释,⽤空格代替
周末闲着没事,我⽤go重新实现了这个功能,感觉应该会有后来⼈可以⽤上
说明:
sql⾥⾯的注释有两种单⾏注释和多⾏注释,其中单⾏注释以--开头,以\n结尾,多⾏注释以/开头,以/结尾
sql字符串是以'开头,'结尾,但特别的地⽅是连续两个单引号是代表⼀个单引号⽽不是字符串结束标志
关键函数如下:
`
/**
将字节数组⾥⾯注释和字符串,⽤空格替换 rangeBeg和rangeEnd是数组元素起始位置左闭右开
*/
func TrimSqlByteArray(sql []byte, rangeBeg int, rangeEnd int) []byte {
sqlLength := rangeEnd - rangeBeg - 1;
//删除注释或者字符串后⽤空格填充必免因删除导致粘连改变sql语义
const chPad = ' '
//结果切⽚,预分配空间为⼊参sql长度⼀半
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是⼀种变长字节编码⽅式。对于某⼀个字符的UTF-8编码,如果只有⼀个字节则其最⾼⼆进制位为0;
//如果是多字节,其第⼀个字节从最⾼位开始,连续的⼆进制位值为1的个数决定了其编码的位数,其余各字节均以10开头。
//UTF-8最多可⽤到6个字节。这⾥不考虑异常,因为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
go字符串转数组//下标移到⾮有效字符的最后
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是数组边界
*/
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字符串⾥⾯连续的单引号被认为是' 则不是字符串结束标志
if ch == '\'' && chNext == '\'' {
result = result + 1;
continue;
} else if ch == '\'' {
break;
}
}
break
default:
break;
}
result++;
return result;
}
到此这篇关于使⽤go实现删除sql⾥⾯的注释和字符串功能的⽂章就介绍到这了,更多相关go删除sql注释和字符串内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论