单句SQL语句的解析方案
2009-02-05 10:20:54 来源:WEB开发网这段代码为什么要逐渐从SQL开头开始截取不断增长的SQL语句进行分析而不是直接对整个SQL进行查找呢?原因是表示子句的正则表达式比较贪婪,它会竭力向后寻找,比如说SQL语句是这样写的:
select .... from .... where .... order by ....
那么用"(from)(.+)( where | on | having | groups+by | orders+by | ENDOFSQL)"进行查找得到from子句不是
from .... where
而是
from .... where .... order by
这当然不是我们想要的结果,因此采取了从SQL开头开始截取不断增长的SQL语句进行分析,找到了from .... where部分就不用继续往下找了,当然这在效率上有降低,但一些效率的付出相对于正确的结果来说是值得的。
4.将片段主体部分劈分开来
还是拿from子句做例子,得到它以后我们希望继续进行分析,最终得到from子句的表,这部分工作比较简单,使用特定的标志对body进行查找劈分即可,from子句的劈分标志较多,用正则表达式写出来是“(,|s+lefts+joins+|s+rights+joins+|s+inners+joins+)”,各种情况都要涉及到。其实大多数子句主体部分的劈分标志都是逗号,用正则表达式写出来都比from子句的简单。
劈分的代码如下,每个分隔符之间的小部分放在链表中:
List<String> ls=new ArrayList<String>();
Pattern p = Pattern.compile(bodySplitPattern,Pattern.CASE_INSENSITIVE);// bodySplitPattern就是劈分的正则表达式
// 先清除掉前后空格
body=body.trim();
Matcher m = p.matcher(body);
StringBuffer sb = new StringBuffer();
boolean result = m.find();
while (result) {
m.appendReplacement(sb, m.group(0) + Crlf);
result = m.find();
}
m.appendTail(sb);
// 再按空行断行
String[] arr=sb.toString().split("[n]+");
int arrLength=arr.length;
for(int i=0;i<arrLength;i++){
String temp=FourSpace+arr[i];
if(i!=arrLength-1){
temp=temp+Crlf;
}
ls.add(temp);
}
更多精彩
赞助商链接