日期:2014-05-20  浏览次数:20798 次

100分~在线急等,正则表达式,分析sql
请教大家个问题,现在想用正则分析一个sql文,找到匹配的from部分和where部分,比如下面的sql
select u.aa,u.bb,t.cc,(select h.bb from hag h where h.bb=0) dd,(select c.bb from cat c where c.tt=1) ee from uss u left join times t on u.ttt=t.ttt where 1=1  

想通过正则分析的得到结果如下
1.from部分 hag h where部分 h.bb=0
2.from部分 cat c where部分 c.tt=1
3.from部分 uss u left join times t on u.ttt=t.ttt where部分 1=1  

小弟正规不太会用,就拜托大家多提建议吧,万分感谢~~

------解决方案--------------------
这个用正则可能不好实现,因为SQL语句可以有很复杂的!
------解决方案--------------------
还是用栈吧
------解决方案--------------------
感觉挺难的……
------解决方案--------------------
确实,由于sql语句很复杂,要写出通用的正则几乎不可能:简单点如
select u.aa,u.bb,t.cc,(select h.bb from hag h where h.bb=0) dd,(select c.bb from cat c where c.tt=1) ee from uss u left join times t on u.ttt=t.ttt where 1=1";
但是比如。。。
select u.aa,u.bb,t.cc,(select h.bb from hag h where h.bb=0 order by h.bb limit 0,1) dd,(select c.bb from cat c where c.tt in(1,2,3)) ee from uss u left join times t on u.ttt=t.ttt where 1=1
是无法搞定的
Java code

    String s1 = "select u.aa,u.bb,t.cc,(select h.bb from hag h where h.bb=0) dd,(select c.bb from cat c where c.tt=1) ee from uss u left join times t on u.ttt=t.ttt where 1=1";
    String s2 = "select u.aa,u.bb,t.cc,(select h.bb from hag h where h.bb=0 order by h.bb limit 0,1) dd,(select c.bb from cat c where c.tt in(1,2,3)) ee from uss u left join times t on u.ttt=t.ttt where 1=1";
    Pattern p = Pattern.compile("\\bfrom\\b([\\s\\w.=']*?)\\bwhere\\b(.*?)(?:\\blimit\\b|\\border\\b|\\)|$)");
    Matcher m = p.matcher(s1);//对s2这种类型的就鞭长莫及了
    while(m.find()){
      System.out.println(m.group(1));
      System.out.println(m.group(2));
    }

------解决方案--------------------
不如果告诉大家你为什么要获取那些内容吧
------解决方案--------------------
为什么啊?
------解决方案--------------------
这个完全没有规则,你知道from从那里结束吗?是单一的,还是复合的!
------解决方案--------------------
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class Test {

public static void main(String[] args){


String s1=" select u.aa,u.bb,t.cc,(select h.bb from hag h where h.bb=0) dd,(select c.bb from cat c where c.tt=1) ee from uss u left join times t on u.ttt=t.ttt where 1=1";

Matcher m=Pattern.compile("(?im)\\bfrom\\b([^(]*?)where\\b(([^()]*?(\\([^()]*?\\)[^()]*?)|([^()]*?))*?)(\\)|$|(\\border)|(\\blimit)|(\\bgroup))").matcher(s1);
while(m.find()){

System.out.println("from部分 "+m.group(1)+" where 部分 "+m.group(2));
}

System.out.println("-----------我是分割线------------");
String s2="select u.aa,u.bb,t.cc,(select h.bb from hag h where h.bb=0 order by h.bb limit 0,1) dd,(select c.bb from cat c where c.tt in(1,2,3) and c.yy in('33','44')) ee from uss u left join times t on u.ttt=t.ttt where 1=1";

m=Pattern.compile("(?im)\\bfrom\\b([^(]*?)where\\b(([^()]*?(\\([^()]*?\\)[^()]*?)|([^()]*?))*?)(\\)|$|(\\border)|(\\blimit)|(\\bgroup))").matcher(s2);
while(m.find()){

System.out.println("from部分 "+m.group(1)+" where 部分 "+m.group(2));
}

}
}


输出
from部分 hag h where 部分 h.bb=0
from部分 cat c where 部分 c.tt=1
from部分 uss u left join times t on u.ttt=t.ttt where 部分 1=1
-----------我是分割线------------
from部分 hag h where 部分 h.bb=0 
from部分 cat c where 部分 c.tt in(1,2,3) and c.yy in('33','44')