<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    春風博客

    春天里,百花香...

    導航

    <2008年3月>
    2425262728291
    2345678
    9101112131415
    16171819202122
    23242526272829
    303112345

    統計

    公告

    MAIL: junglesong@gmail.com
    MSN: junglesong_5@hotmail.com

    Locations of visitors to this page

    常用鏈接

    留言簿(11)

    隨筆分類(224)

    隨筆檔案(126)

    個人軟件下載

    我的其它博客

    我的鄰居們

    最新隨筆

    搜索

    積分與排名

    最新評論

    閱讀排行榜

    評論排行榜

    一個利用正則表達式解析單句SQL的類SqlParser

    本文乃原創,轉載請注明出處。

    先看要解析的樣例SQL語句:
    select * from dual
    SELECT * frOm dual
    Select C1,c2 From tb
    select c1,c2 from tb
    select count(*from t1
    select c1,c2,c3 from t1 where condi1=1 
    Select c1,c2,c3 From t1 Where condi1=1 
    select c1,c2,c3 from t1,t2 where condi3=3 or condi4=5 order   by o1,o2
    Select c1,c2,c3 from t1,t2 Where condi3=3 or condi4=5 Order   by o1,o2
    select c1,c2,c3 from t1,t2,t3 where condi1=5 and condi6=6 or condi7=7 group  by g1,g2
    Select c1,c2,c3 From t1,t2,t3 Where condi1=5 and condi6=6 or condi7=7 Group  by g1,g2
    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

    解析效果之一(isSingleLine=false):
    原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


    解析效果之二(isSingleLine=true):
    原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<String> getParsedSqlList(){
            List
    <String> sqlList=new ArrayList<String>();
            
            
    // 無法解析則原樣返回
            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
    <String> ls=new ArrayList<String>();
            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);
            }
        }
    }

    posted on 2008-03-14 20:08 sitinspring 閱讀(7610) 評論(10)  編輯  收藏 所屬分類: 個人作品

    評論

    # re: 一個利用正則表達式解析單句SQL的類SqlParser 2008-03-15 20:42 lingos

    你這解析了干嘛用?  回復  更多評論   

    # re: 一個利用正則表達式解析單句SQL的類SqlParser 2008-03-16 11:48 如坐春風

    @lingos

    用在我的一個小工具中。
    http://download.enet.com.cn/html/030212008012701.html  回復  更多評論   

    # re: 一個利用正則表達式解析單句SQL的類SqlParser 2008-03-17 09:30 CowNew開源團隊

    Great job!
    另外也可以使用我們CowNewSQL中的SQL解析器,已經可以解析非常復雜的SQL語句了。CowNewSQL的SQL解析器部分可以單獨拿出來使用。  回復  更多評論   

    # re: 一個利用正則表達式解析單句SQL的類SqlParser 2008-03-17 20:00 如坐春風

    @CowNew開源團隊

    謝謝。

    你們的解析器我剛來Blogjava就聽說過,也有想用的念頭,只是不知道它是免費的還是協議的,能否用在我的小沒有開源的工具中。 也沒去問你們,自己寫的權當是練手了。以后我會考慮使用貴團隊的SQL解析器的。

      回復  更多評論   

    # re: 一個利用正則表達式解析單句SQL的類SqlParser 2008-03-17 20:03 CowNew開源團隊

    @如坐春風
    可以使用的。我們的解析器是LGPL協議的,所以可以用在私有軟件中。具體可以參考LGPL協議,:)。如果在使用過程中有問題可以和我們聯系,:)。  回復  更多評論   

    # re: 一個利用正則表達式解析單句SQL的類SqlParser 2008-03-17 20:07 如坐春風

    @CowNew開源團隊

    回帖好快啊!

    你們的地址我記下了,忙完這陣我一定會拜訪的。  回復  更多評論   

    # re: 一個利用正則表達式解析單句SQL的類SqlParser 2008-04-26 11:04 wsand

    select c1,c2,c3 from t1,t2 order by o1,o2
    沒有where,測試一下  回復  更多評論   

    # re: 一個利用正則表達式解析單句SQL的類SqlParser 2011-05-05 15:11 謝宇

    既然是簡單表達式我也不說太難的例子,我只說一個,麻煩幫忙解決一下,就是字段里面有from關鍵字,但是不是from,比如fromaddr,這種。

    select fromaddr from abc;

    我試了下解析出來好像是錯的,作者可以試一試。
    另外至于SQL中有常量的情況,常量中包含關鍵字的問題,估計會更加復雜一些;SQL文本中如果存在中文全格的空格作者是否有想過如何解決。

    更復雜的當然是各類SQL的寫法了,尤其是一些方言SQL,但是由于作者只提到簡單SQL我覺得至少是說明單條SQL是可以處理吧;前面兩個問題應該可以考慮下如何避免。  回復  更多評論   

    # re: 一個利用正則表達式解析單句SQL的類SqlParser[未登錄] 2011-09-15 02:19 aa

    沒有解析子查詢  回復  更多評論   

    # re: 一個利用正則表達式解析單句SQL的類SqlParser[未登錄] 2014-01-20 13:58 Jason

    不錯,解析出來剛好要使用的東西。  回復  更多評論   

    sitinspring(http://www.tkk7.com)原創,轉載請注明出處.
    主站蜘蛛池模板: 美女内射无套日韩免费播放| 日本系列1页亚洲系列| 亚洲无码黄色网址| 最近高清国语中文在线观看免费| 亚洲精品视频在线观看视频| 亚洲人成电影在线播放| 国产精品免费播放| 国产成人免费网站| 114级毛片免费观看| a级毛片黄免费a级毛片| 一级做a爰片久久毛片免费看 | 国产AV日韩A∨亚洲AV电影 | 最近高清国语中文在线观看免费| 久久久久久影院久久久久免费精品国产小说| 精品亚洲国产成人av| 久久狠狠爱亚洲综合影院| 久久亚洲美女精品国产精品| 亚洲码国产精品高潮在线| 亚洲偷自拍拍综合网| 亚洲区小说区图片区| 亚洲国产V高清在线观看| 四虎影永久在线高清免费| 国内自产拍自a免费毛片| 免费精品视频在线| 亚洲国产精品成人午夜在线观看| 亚洲伊人久久大香线蕉综合图片| 亚洲人成影院在线观看| 国产精品亚洲mnbav网站| 亚洲国产精品成人| 亚洲精品tv久久久久| 亚洲国产精品狼友中文久久久| 日本一道本高清免费| 免费看男女下面日出水视频| 日本无吗免费一二区| 四虎永久免费观看| 亚洲成AV人网址| 亚洲综合精品网站| 亚洲综合另类小说色区色噜噜| 亚洲一区二区女搞男| 亚洲综合伊人久久综合| 亚洲精品国偷自产在线|