博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用正则表达式解析语句
阅读量:4121 次
发布时间:2019-05-25

本文共 3627 字,大约阅读时间需要 12 分钟。

使用正则表达式解析SQL语句

问题:将左边的SQL语句解析成右边的形式

Select c1,c2,c3 From t1,t2,t3 Where condi1=5 and condi6=6 or condi7=7 Group by g1,g2,g3 order by g2,g3

select

c1,

c2,

c3

from

t1,

t2,

t3

where

condi1=5 and

condi6=6 or

condi7=7

group by

g1,

g2,

g3

order by

g2,

g3

按关键字找出
SQL语句中各部分

我们阅读
SQL语句会把整句分来成列,表,条件,分组字段,排序字段来理解,解析
SQL的目的也是这样.

分解
SQL语句有规律可循,以列为例,它必定包含在select和from之间,我们只要能找到
SQL语句中的关键字select和from,就能找到查询的列.

怎么找到select和from之间的文字呢?其实一个正则表达式就能解决:(select)(.+)(from),其中第二组(.+)代表的文字就是select和from之间的文字.

程序见右边.

/*** 从文本text中找到regex首次匹配的字符串,不区分大小写

* @param regex: 正则表达式

* @param text:欲查找的字符串

* @return regex首次匹配的字符串,如未匹配返回空*/

private static String getMatchedString(String regex,String text){

Pattern pattern=Pattern.compile(regex,Pattern.CASE_INSENSITIVE);

Matcher matcher=pattern.matcher(text);

while(matcher.find()){

return matcher.group(2);

}

return null;

}

解析函数分析

private static String getMatchedString(String regex,String text){

Pattern pattern=Pattern.compile(regex,Pattern.CASE_INSENSITIVE);

Matcher matcher=pattern.matcher(text);

while(matcher.find()){

return matcher.group(2);

}

return null;

}

左边的这个函数,第一个参数是拟定的正则表达式,第二个是整个
SQL语句.

当正则表达式为(select)(.+)(from)时,程序将在
SQL中查找第一次匹配的地方(有Pattern.CASE_INSENSITIVE的设置,查找不区分大小写),如果找到了则返回模式中的第二组代表的文字.

如果
sql是select a,b from tc,则返回的文字是a,b.

选择的表对应的查找正则表达式

选择的表比较特殊,它不想选择的列一样固定处于select和from之间,当没有查找条件存在时,它处于from和结束之间;当有查找条件存在时,它处于from和where之间.

因此查询函数写为右边的形式:

/*** 解析选择的表**/

private void parseTables(){

String regex="";

if(isContains(
sql,"\\s+where\\s+")){

regex="(from)(.+)(where)";

}

else{

regex="(from)(.+)($)";

}

tables=getMatchedString(regex,
sql);

}

isContains函数

isContains函数用于在lineText中查找word,其中不区分大小些,只要找到了即返回真.

/*** 看word是否在lineText中存在,支持正则表达式

* @param lineText

* @param word

* @return*/

private static boolean isContains(String lineText,String word){

Pattern pattern=Pattern.compile(word,Pattern.CASE_INSENSITIVE);

Matcher matcher=pattern.matcher(lineText);

return matcher.find();

}

解析查找条件的函数

private void parseConditions(){

String regex="";

if(isContains(
sql,"\\s+where\\s+")){

// 包括Where,有条件

if(isContains(
sql,"group\\s+by")){

// 条件在where和group by之间

regex="(where)(.+)(group\\s+by)";

}

else if(isContains(
sql,"order\\s+by")){

// 条件在where和order by之间

regex="(where)(.+)(order\\s+by)";

}

else{

// 条件在where到字符串末尾

regex="(where)(.+)($)";

}}

else{// 不包括where则条件无从谈起,返回即可

return;}

conditions=getMatchedString(regex,
sql);

}

解析GroupBy的字段

private void parseGroupCols(){

String regex="";

if(isContains(
sql,"group\\s+by")){

// 包括GroupBy,有分组字段

if(isContains(
sql,"order\\s+by")){

// group by 后有order by

regex="(group\\s+by)(.+)(order\\s+by)";

}

else{

// group by 后无order by

regex="(group\\s+by)(.+)($)";

}}

else{// 不包括GroupBy则分组字段无从谈起,返回即可

return;

}

groupCols=getMatchedString(regex,
sql);

}

解析OrderBy的字段

private void parseOrderCols(){

String regex="";

if(isContains(
sql,"order\\s+by")){

// 包括order by,有分组字段

regex="(order\\s+by)(.+)($)";

}

else{

// 不包括GroupBy则分组字段无从谈起,返回即可

return;

}

orderCols=getMatchedString(regex,
sql);

}

得到解析后的各部分

按以上解析方法获得了列,表,条件,分组条件,排序条件各部分之后,它们会存储到各个成员变量中.

注意这些成员变量的原值都是null,如果在
SQL语句中能够找到对应的部分的话它们将借助getMatchedString获得值,否则还是null.我们通过判断这些成员变量是否为空就能知道它对应的部分是否被解析出来.

/*** 待解析的
SQL语句*/

private String 
sql;

/*** 
SQL中选择的列*/

private String cols;

/*** 
SQL中查找的表*/

private String tables;

/*** 查找条件*/

private String conditions;

/*** Group By的字段*/

private String groupCols;

/*** Order by的字段*/

private String orderCols;

取得不需要单行显示时的
SQL语句

进展到这一步,
SQL语句中列,表,条件,分组条件,排序条件各部分都被获取了出来,这时把它们重新组合一下就能得到整理后的
SQL语句.

如下面的
SQL语句将变成右边的部分(先使静态成员isSingleLine=false):

Select c1,c2,c3 From t1,t2,t3 Where condi1=5 and condi6=6 or condi7=7 Group by g1,g2,g3 order by g2,g3

select

c1,c2,c3

from

t1,t2,t

转载地址:http://yzxpi.baihongyu.com/

你可能感兴趣的文章
虚拟机 CentOS7/RedHat7/OracleLinux7 配置静态IP地址 Ping 物理机和互联网
查看>>
弱类型、强类型、动态类型、静态类型语言的区别是什么?
查看>>
Struts2技术内幕图书 转载
查看>>
Java异常分类
查看>>
项目中的jackson与json-lib使用比较
查看>>
Jackson Tree Model Example
查看>>
j2ee-验证码
查看>>
日志框架logj的使用
查看>>
js-高德地图规划路线
查看>>
常用js收集
查看>>
mydata97的日期控件
查看>>
如何防止sql注入
查看>>
maven多工程构建与打包
查看>>
springmvc传值
查看>>
Java 集合学习一 HashSet
查看>>
在Eclipse中查看Android源码
查看>>
Android使用webservice客户端实例
查看>>
层在页面中的定位
查看>>
[转]C语言printf
查看>>
C 语言 学习---获取文本框内容及字符串拼接
查看>>