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

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

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

    春風(fēng)博客

    春天里,百花香...

    導(dǎo)航

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

    統(tǒng)計(jì)

    公告

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

    Locations of visitors to this page

    常用鏈接

    留言簿(11)

    隨筆分類(224)

    隨筆檔案(126)

    個(gè)人軟件下載

    我的其它博客

    我的鄰居們

    最新隨筆

    搜索

    積分與排名

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    一個(gè)利用正則表達(dá)式解析單句SQL的類SqlParser

    本文乃原創(chuàng),轉(zhuǎn)載請(qǐng)注明出處。

    先看要解析的樣例SQL語(yǔ)句:
    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,你可以拷貝下來(lái)使用之:
    package com.sitinspring.common.sqlFormatter;

    import java.util.ArrayList;
    import java.util.List;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;

    /**
     * SQL語(yǔ)句解析器類
     * 
    @author: sitinspring(junglesong@gmail.com)
     * @date: 2008-3-12
     
    */
    public class SqlParser{
        
    /**
         * 逗號(hào)
         
    */
        
    private static final String Comma = ",";
        
        
    /**
         * 四個(gè)空格
         
    */
        
    private static final String FourSpace = "    ";
        
        
    /**
         * 是否單行顯示字段,表,條件的標(biāo)識(shí)量
         
    */
        
    private static boolean isSingleLine=true;
        
        
    /**
         * 待解析的SQL語(yǔ)句
         
    */
        
    private String sql;
        
        
    /**
         * SQL中選擇的列
         
    */
        
    private String cols;
        
        
    /**
         * SQL中查找的表
         
    */
        
    private String tables;
        
        
    /**
         * 查找條件
         
    */
        
    private String conditions;
        
        
    /**
         * Group By的字段
         
    */
        
    private String groupCols;
        
        
    /**
         * Order by的字段
         
    */
        
    private String orderCols;
        
        
    /**
         * 構(gòu)造函數(shù)
         * 功能:傳入構(gòu)造函數(shù),解析成字段,表,條件等
         * 
    @param sql:傳入的SQL語(yǔ)句
         
    */
        
    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則條件無(wú)從談起,返回即可
                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 后無(wú)order by
                    regex="(group\\s+by)(.+)($)";  
                }           
            }
            
    else{
                
    // 不包括GroupBy則分組字段無(wú)從談起,返回即可
                return;
            }
            
            groupCols
    =getMatchedString(regex,sql);
        }
        
        
    /**
         * 解析OrderBy的字段
         *
         
    */
        
    private void parseOrderCols(){
            String regex
    ="";   
            
            
    if(isContains(sql,"order\\s+by")){
                
    // 包括GroupBy,有分組字段
                regex="(order\\s+by)(.+)($)";                           
            }
            
    else{
                
    // 不包括GroupBy則分組字段無(wú)從談起,返回即可
                return;
            }
                
            orderCols
    =getMatchedString(regex,sql);
        }
        
        
        
    /**
         * 從文本text中找到regex首次匹配的字符串,不區(qū)分大小寫(xiě)
         * 
    @param regex: 正則表達(dá)式
         * 
    @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中存在,支持正則表達(dá)式
         * 
    @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(){        
            
    // 無(wú)法解析則原樣返回
            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()方法生成一個(gè)Matcher對(duì)象
            Matcher m = p.matcher(str);
            StringBuffer sb 
    = new StringBuffer();

            
    // 使用find()方法查找第一個(gè)匹配的對(duì)象
            boolean result = m.find();

            
    // 使用循環(huán)找出模式匹配的內(nèi)容替換之,再將內(nèi)容加到sb里
            while (result) {
                m.appendReplacement(sb, m.group(
    0+ "\n     ");
                result 
    = m.find();
            }
            
    // 最后調(diào)用appendTail()方法將最后一次匹配后的剩余字符串加到sb里;
            m.appendTail(sb);
            
            
    return FourSpace+sb.toString();
        }
        
        
    /**
         * 取得解析的SQL字符串列表
         * 
    @return
         
    */
        
    public List<String> getParsedSqlList(){
            List
    <String> sqlList=new ArrayList<String>();
            
            
    // 無(wú)法解析則原樣返回
            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;
        }
        
        
    /**
         * 設(shè)置是否單行顯示表,字段,條件等
         * 
    @param isSingleLine
         
    */
        
    public static void setSingleLine(boolean isSingleLine) {
            SqlParser.isSingleLine 
    = isSingleLine;
        }
        
        
    /**
         * 測(cè)試
         * 
    @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) 評(píng)論(10)  編輯  收藏 所屬分類: 個(gè)人作品

    評(píng)論

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

    你這解析了干嘛用?  回復(fù)  更多評(píng)論   

    # re: 一個(gè)利用正則表達(dá)式解析單句SQL的類SqlParser 2008-03-16 11:48 如坐春風(fēng)

    @lingos

    用在我的一個(gè)小工具中。
    http://download.enet.com.cn/html/030212008012701.html  回復(fù)  更多評(píng)論   

    # re: 一個(gè)利用正則表達(dá)式解析單句SQL的類SqlParser 2008-03-17 09:30 CowNew開(kāi)源團(tuán)隊(duì)

    Great job!
    另外也可以使用我們CowNewSQL中的SQL解析器,已經(jīng)可以解析非常復(fù)雜的SQL語(yǔ)句了。CowNewSQL的SQL解析器部分可以單獨(dú)拿出來(lái)使用。  回復(fù)  更多評(píng)論   

    # re: 一個(gè)利用正則表達(dá)式解析單句SQL的類SqlParser 2008-03-17 20:00 如坐春風(fēng)

    @CowNew開(kāi)源團(tuán)隊(duì)

    謝謝。

    你們的解析器我剛來(lái)Blogjava就聽(tīng)說(shuō)過(guò),也有想用的念頭,只是不知道它是免費(fèi)的還是協(xié)議的,能否用在我的小沒(méi)有開(kāi)源的工具中。 也沒(méi)去問(wèn)你們,自己寫(xiě)的權(quán)當(dāng)是練手了。以后我會(huì)考慮使用貴團(tuán)隊(duì)的SQL解析器的。

      回復(fù)  更多評(píng)論   

    # re: 一個(gè)利用正則表達(dá)式解析單句SQL的類SqlParser 2008-03-17 20:03 CowNew開(kāi)源團(tuán)隊(duì)

    @如坐春風(fēng)
    可以使用的。我們的解析器是LGPL協(xié)議的,所以可以用在私有軟件中。具體可以參考LGPL協(xié)議,:)。如果在使用過(guò)程中有問(wèn)題可以和我們聯(lián)系,:)。  回復(fù)  更多評(píng)論   

    # re: 一個(gè)利用正則表達(dá)式解析單句SQL的類SqlParser 2008-03-17 20:07 如坐春風(fēng)

    @CowNew開(kāi)源團(tuán)隊(duì)

    回帖好快啊!

    你們的地址我記下了,忙完這陣我一定會(huì)拜訪的。  回復(fù)  更多評(píng)論   

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

    select c1,c2,c3 from t1,t2 order by o1,o2
    沒(méi)有where,測(cè)試一下  回復(fù)  更多評(píng)論   

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

    既然是簡(jiǎn)單表達(dá)式我也不說(shuō)太難的例子,我只說(shuō)一個(gè),麻煩幫忙解決一下,就是字段里面有from關(guān)鍵字,但是不是from,比如fromaddr,這種。

    select fromaddr from abc;

    我試了下解析出來(lái)好像是錯(cuò)的,作者可以試一試。
    另外至于SQL中有常量的情況,常量中包含關(guān)鍵字的問(wèn)題,估計(jì)會(huì)更加復(fù)雜一些;SQL文本中如果存在中文全格的空格作者是否有想過(guò)如何解決。

    更復(fù)雜的當(dāng)然是各類SQL的寫(xiě)法了,尤其是一些方言SQL,但是由于作者只提到簡(jiǎn)單SQL我覺(jué)得至少是說(shuō)明單條SQL是可以處理吧;前面兩個(gè)問(wèn)題應(yīng)該可以考慮下如何避免。  回復(fù)  更多評(píng)論   

    # re: 一個(gè)利用正則表達(dá)式解析單句SQL的類SqlParser[未登錄](méi) 2011-09-15 02:19 aa

    沒(méi)有解析子查詢  回復(fù)  更多評(píng)論   

    # re: 一個(gè)利用正則表達(dá)式解析單句SQL的類SqlParser[未登錄](méi) 2014-01-20 13:58 Jason

    不錯(cuò),解析出來(lái)剛好要使用的東西。  回復(fù)  更多評(píng)論   

    sitinspring(http://www.tkk7.com)原創(chuàng),轉(zhuǎn)載請(qǐng)注明出處.
    主站蜘蛛池模板: h视频在线观看免费完整版| 国产成人亚洲精品狼色在线| 久久精品国产亚洲香蕉| 男人的天堂av亚洲一区2区| 免费人妻无码不卡中文字幕系| 亚洲福利精品一区二区三区| 亚洲精品亚洲人成在线播放| 一区二区三区观看免费中文视频在线播放 | 2021在线观看视频精品免费| 久久精品国产精品亚洲人人| 亚洲日韩AV无码一区二区三区人| 污网站免费在线观看| 三年片免费高清版 | 免费无码AV电影在线观看| 国产亚洲综合成人91精品| 国产成人高清亚洲一区91| 无码国产精品久久一区免费| 久久亚洲AV成人出白浆无码国产 | 亚洲国产精品无码久久九九| 亚洲色大成网站www尤物| 亚欧免费视频一区二区三区| 亚洲AV永久无码精品成人| 产传媒61国产免费| 国产精品久免费的黄网站| 亚洲综合偷自成人网第页色| 国产2021精品视频免费播放| 亚洲日本精品一区二区 | 9277手机在线视频观看免费| 亚洲va久久久噜噜噜久久狠狠| 一级毛片免费一级直接观看| 国产成人免费全部网站| 亚洲精品永久在线观看| 猫咪社区免费资源在线观看| 亚洲国产午夜精品理论片| 91青青国产在线观看免费| 久久亚洲国产精品| 国内精品免费视频精选在线观看 | 亚洲精品中文字幕| 天堂在线免费观看中文版| 亚洲一本到无码av中文字幕| 四虎国产精品免费久久|