<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)原創,轉載請注明出處.
    主站蜘蛛池模板: 很黄很污的网站免费| 毛片免费在线观看网站| 亚洲一区二区三区91| 国产高清在线精品免费软件| 国产精品美女免费视频观看| 亚洲区视频在线观看| 亚洲成A人片在线观看中文| 无码一区二区三区免费| 亚洲GV天堂无码男同在线观看 | 永久免费毛片手机版在线看| 中文字幕无线码免费人妻| 亚洲一级片在线播放| 精品亚洲综合在线第一区| 女人与禽交视频免费看| a毛片在线还看免费网站| 亚洲欧美日韩一区二区三区在线| 久久久久久久综合日本亚洲| 超pen个人视频国产免费观看| a级毛片在线免费看| 久久亚洲精品11p| 亚洲白色白色永久观看| 自拍偷自拍亚洲精品第1页| 女人18毛片水真多免费播放| 久久久久久AV无码免费网站| 四虎影视永久在线精品免费| 亚洲一线产品二线产品| 亚洲综合成人网在线观看| 亚洲高清视频一视频二视频三| av无码久久久久不卡免费网站| a色毛片免费视频| 猫咪免费观看人成网站在线| 亚洲人成毛片线播放| 亚洲av无码乱码国产精品| 免费播放春色aⅴ视频| 成年女性特黄午夜视频免费看| 蜜桃成人无码区免费视频网站 | 一级一级一级毛片免费毛片| 日韩亚洲产在线观看| 亚洲高清中文字幕综合网| 亚洲中文字幕无码一区二区三区| 国产一级一片免费播放i|