请教大家个问题,现在想用正则分析一个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  小弟正规不太会用,就拜托大家多提建议吧,万分感谢~~

解决方案 »

  1.   

    这个用正则可能不好实现,因为SQL语句可以有很复杂的!
      

  2.   

    确实,由于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
    是无法搞定的    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));
        }
      

  3.   

    辛苦大家了,
    其实,我是想取from部分的表名,再在它对应的where部分,加上一些相关的条件。
    所以,先要取到from部分,再取对应的where部分如果有好的方法,尽管发上来哈,
      

  4.   

    这个完全没有规则,你知道from从那里结束吗?是单一的,还是复合的!
      

  5.   

    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')
    from部分   uss u left join times t on u.ttt=t.ttt  where 部分  1=1
    说明:
     1)按照楼主的格式,from部分是m.group(1),where部分是m.group(2)
     2)可以多行匹配
     3)分割线下面解决4楼提出的,where部分存在成对出现的()问题
     4)where后面如果出现括号,必须成对出现,否则匹配结束。where后面遇到单个的)或行结束符或group或order或。limit认为where部分结束
      

  6.   

    正则表达式是字符串处理工具,并不是语法分析工具,更不是编译器!要进行 SQL 的语法分析,使用正则表达式是完不成的,即使能做到也只能满足于特定的环境。如果确实需要进行语法分析,可以使用 Antlr 这个 Java 工具。
      

  7.   

    正则表达式对语法的解析问题的能力确实不够,需要考虑的东西太多,有人写过词法分析器之类的东西,可惜没我看懂,你可以去google看下