原SQL为select * from dual

解析后的SQL为

select

*

from

dual

原SQL为SELECT * frOm dual

解析后的SQL为

select

*

from

dual

原SQL为Select C1,c2 From tb

解析后的SQL为

select

C1,

c2

from

tb

原SQL为select c1,c2 from tb

解析后的SQL为

select

c1,

c2

from

tb

原SQL为select count(*) from t1

解析后的SQL为

select

count(*)

from

t1

原SQL为select c1,c2,c3 from t1 where condi1=1

解析后的SQL为

select

c1,

c2,

c3

from

t1

where

condi1=1

原SQL为Select c1,c2,c3 From t1 Where condi1=1

解析后的SQL为

select

c1,

c2,

c3

from

t1

where

condi1=1

原SQL为select c1,c2,c3 from t1,t2 where condi3=3 or condi4=5 order by o1,o2

解析后的SQL为

select

c1,

c2,

c3

from

t1,

t2

where

condi3=3 or

condi4=5

order by

o1,

o2

原SQL为Select c1,c2,c3 from t1,t2 Where condi3=3 or condi4=5 Order by o1,o2

解析后的SQL为

select

c1,

c2,

c3

from

t1,

t2

where

condi3=3 or

condi4=5

order by

o1,

o2

原SQL为select c1,c2,c3 from t1,t2,t3 where condi1=5 and condi6=6 or condi7=7 group by g1,g2

解析后的SQL为

select

c1,

c2,

c3

from

t1,

t2,

t3

where

condi1=5 and

condi6=6 or

condi7=7

group by

g1,

g2

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

解析后的SQL为

select

c1,

c2,

c3

from

t1,

t2,

t3

where

condi1=5 and

condi6=6 or

condi7=7

group by

g1,

g2

原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

解析后的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

使用的类SqlParser,你可以拷贝下来使用之:

代码如下:package com.sitinspring.common.sqlFormatter;

import java.util.ArrayList;

import java.util.List;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

/**

* SQL语句解析器类

* @author: sitinspring(junglesong@gmail.com)

* @date: 2008-3-12

*/

public class SqlParser{

/**

* 逗号

*/

private static final String Comma = ",";

/**

* 四个空格

*/

private static final String FourSpace = " ";

/**

* 是否单行显示字段,表,条件的标识量

*/

private static boolean isSingleLine=true;

/**

* 待解析的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;

/**

* 构造函数

* 功能:传入构造函数,解析成字段,表,条件等

* @param sql:传入的SQL语句

*/

public SqlParser(String sql){

this.sql=sql.trim();

parseCols();

parseTables();

parseConditions();

parseGroupCols();

parseOrderCols();

}

/**

* 解析选择的列

*

*/

private void parseCols(){

String regex="(select)(.+)(from)";

cols=getMatchedString(regex,sql);

}

/**

* 解析选择的表

*

*/

private void parseTables(){

String regex="";

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

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

}

else{

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

}

tables=getMatchedString(regex,sql);

}

/**

* 解析查找条件

*

*/

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")){

// 包括GroupBy,有分组字段

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

}

else{

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

return;

}

orderCols=getMatchedString(regex,sql);

}

/**

* 从文本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;

}

/**

* 看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();

}

public String toString(){

// 无法解析则原样返回

if(cols==null && tables==null && conditions==null && groupCols==null && orderCols==null ){

return sql;

}

StringBuffer sb=new StringBuffer();

sb.append("原SQL为"+sql+"\n");

sb.append("解析后的SQL为\n");

for(String str:getParsedSqlList()){

sb.append(str);

}

sb.append("\n");

return sb.toString();

}

/**

* 在分隔符后加上回车

* @param str

* @param splitStr

* @return

*/

private static String getAddEnterStr(String str,String splitStr){

Pattern p = Pattern.compile(splitStr,Pattern.CASE_INSENSITIVE);

// 用Pattern类的matcher()方法生成一个Matcher对象

Matcher m = p.matcher(str);

StringBuffer sb = new StringBuffer();

// 使用find()方法查找第一个匹配的对象

boolean result = m.find();

// 使用循环找出模式匹配的内容替换之,再将内容加到sb里

while (result) {

m.appendReplacement(sb, m.group(0) + "\n ");

result = m.find();

}

// 最后调用appendTail()方法将最后一次匹配后的剩余字符串加到sb里;

m.appendTail(sb);

return FourSpace+sb.toString();

}

/**

* 取得解析的SQL字符串列表

* @return

*/

public List getParsedSqlList(){

List sqlList=new ArrayList();

// 无法解析则原样返回

if(cols==null && tables==null && conditions==null && groupCols==null && orderCols==null ){

sqlList.add(sql);

return sqlList;

}

if(cols!=null){

sqlList.add("select\n");

if(isSingleLine){

sqlList.add(getAddEnterStr(cols,Comma));

}

else{

sqlList.add(FourSpace+cols);

}

}

if(tables!=null){

sqlList.add(" \nfrom\n");

if(isSingleLine){

sqlList.add(getAddEnterStr(tables,Comma));

}

else{

sqlList.add(FourSpace+tables);

}

}

if(conditions!=null){

sqlList.add(" \nwhere\n");

if(isSingleLine){

sqlList.add(getAddEnterStr(conditions,"(and|or)"));

}

else{

sqlList.add(FourSpace+conditions);

}

}

if(groupCols!=null){

sqlList.add(" \ngroup by\n");

if(isSingleLine){

sqlList.add(getAddEnterStr(groupCols,Comma));

}

else{

sqlList.add(FourSpace+groupCols);

}

}

if(orderCols!=null){

sqlList.add(" \norder by\n");

if(isSingleLine){

sqlList.add(getAddEnterStr(orderCols,Comma));

}

else{

sqlList.add(FourSpace+orderCols);

}

}

return sqlList;

}

/**

* 设置是否单行显示表,字段,条件等

* @param isSingleLine

*/

public static void setSingleLine(boolean isSingleLine) {

SqlParser.isSingleLine = isSingleLine;

}

/**

* 测试

* @param args

*/

public static void main(String[] args){

List ls=new ArrayList();

ls.add("select * from dual");

ls.add("SELECT * frOm dual");

ls.add("Select C1,c2 From tb");

ls.add("select c1,c2 from tb");

ls.add("select count(*) from t1");

ls.add("select c1,c2,c3 from t1 where condi1=1 ");

ls.add("Select c1,c2,c3 From t1 Where condi1=1 ");

ls.add("select c1,c2,c3 from t1,t2 where condi3=3 or condi4=5 order by o1,o2");

ls.add("Select c1,c2,c3 from t1,t2 Where condi3=3 or condi4=5 Order by o1,o2");

ls.add("select c1,c2,c3 from t1,t2,t3 where condi1=5 and condi6=6 or condi7=7 group by g1,g2");

ls.add("Select c1,c2,c3 From t1,t2,t3 Where condi1=5 and condi6=6 or condi7=7 Group by g1,g2");

ls.add("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");

for(String sql:ls){

System.out.println(new SqlParser(sql));

//System.out.println(sql);

}

}

}

本条技术文章来源于互联网,如果无意侵犯您的权益请点击此处反馈版权投诉

本文系统来源:php中文网

解析单句sql_SqlParser 一个利用正则表达式解析单句SQL的类相关推荐

  1. python 解析pb文件_利用Python解析json文件

    写在前面 在金融风控领域,我们经常会使用到json格式的数据,例如运营商数据.第三方数据等.而这些数据往往不能直接作为结构化数据进行分析和建模.本文将介绍一种简单的.可复用性高的基于pandas的方法 ...

  2. (二)Java解析XML:一个简单的解析XML文件的例子

    先假设有如下格式的XML文件: <test name="test"><service id="create"><class pat ...

  3. 一个利用正则表达式进行代码重构,去除冗余代码的例子

    refact之前:大量的重复代码 refact之后:用map消除了重复代码. 现在的分支里每次执行检查都要先 var usRegx = /XXXX/. 实际上通过字面量定义了一个正则表达式对象,开销比 ...

  4. java解析lrc_java中用正则表达式解析LRC文件

    跟着Mars老师 一起写android中的Mp3播放器 真是受益匪浅 再次感谢老师的无私奉献 不过其中问题也确实不少 感觉老师的代码重构做的不够 其中对LRC文件的解析也弄的比较马虎 今天特意花了一天 ...

  5. PHP 利用json_decode解析json为null问题解决

    PS:原创文章,如需转载,请注明出处,谢谢! 本文地址:http://flyer0126.iteye.com/blog/2382708 今天遇到json解析问题,PHP利用json_decode解析j ...

  6. 【Java 解析全国地址】Java 利用正则表达式完美解析全国省市区地址

    Java 利用正则表达式完美解析全国省市区地址 一.问题场景描述 最近在项目中遇到了一个全国地址解析的一个场景,前端会传来一个字符串,后端需自动解析出 xx省xx市xx区+详细地址 的这种格式. 因为 ...

  7. jsoup解析和遍历一个html文档详解

    解析和遍历一个HTML文档 如何解析一个HTML文档: String html = "<html><head><title>First parse< ...

  8. python爬虫正则表达式实例-python爬虫 正则表达式解析

    这篇文章主要介绍了python爬虫 正则表达式解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 - re.I # 忽略大小写 - re.M # 多 ...

  9. 万物之始正则表达式全解析三部曲(中篇)-正则表达式运算符优先级及匹配规则

    前言 各位小伙伴大家好,接下来几天时间,我会从多个角度对正则表达式进行系统阐述,让你了解正则表达式的前世今生. 该系列文章上篇 万物之始正则表达式全解析三部曲(上篇)-正则表达式基础知识及语法 以下是 ...

最新文章

  1. 每日一句英语:怎样回答美国人的How is it going问候语?
  2. nable to execute dex: Multiple dex files define Lcom/chinaCEB/cebActivity/R
  3. uniGUI试用笔记(十一)
  4. 项目使用了redis还需要mysql_【11-05】lnmp项目中Redis和Mysql配合使用应该注意哪些问题?...
  5. oracle使用关键字做表字段名_ArcGIS SQL使用
  6. openmpi安装_Intel Parallel Studio XE 2019安装设置
  7. Numpy 字符串处理
  8. git中fatal: Authentication failed的问题 git不能clone
  9. 永久的CheckBox(单选,全选/反选)!
  10. ACM 学习笔记(二) 位运算、并查集、模拟、枚举、递推、递归
  11. 寒假学习之stm32(15)----DMA(direct memory access)
  12. 生物医学信号处理之数字信号处理基础
  13. java实现使用POI对word文档的页眉页脚的编辑
  14. Java 小Q 世界上最遥远的距离 解法二
  15. 【英语-同义词汇词组】due to的用法及相关词组(because of | owing to)的用法区别
  16. nano编辑器保存退出
  17. Python 自然语言处理(基于jieba分词和NLTK)
  18. log4j日志打印异常堆栈信息。
  19. linux 下 调笔记本亮度,Linux下如何保存笔记本屏幕亮度设置(背光亮度)
  20. 十款强大的图像后期处理软件和工具

热门文章

  1. 基于知识图谱的推荐系统总结
  2. 【报告分享】2021年30+精致女性人群需求洞察:“她”经济时代科技引领精致生活.pdf(附下载链接)...
  3. 【报告分享】人工智能之未来产业智能----新价值、新边界、新格局.pdf(附下载链接)...
  4. 图形学必备!斯坦福图形学几何处理算法课程1——Surface Reconstruction
  5. 动荡下如何自救 | 社招一年收割BATDK算法offer
  6. find python3_Python3 rfind()方法
  7. 让php来搞定一切!,ubuntu安装和配置php5
  8. Leetcode刷题之旅1
  9. 链表的C++创建及翻转
  10. 反射实现方法调用(1):执行机制