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

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

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

    當柳上原的風吹向天際的時候...

    真正的快樂來源于創造

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      368 Posts :: 1 Stories :: 201 Comments :: 0 Trackbacks
    編程中有時需要將一段文本分解成標記,比如說14+2*3需要變成14,+,2,*,3的樣式,再比如說select a from b,需要變成select,a,from,b的形式,要寫出這樣的代碼不難,考慮到通用性,于是我制作了下面這個通用類,用戶只需要指定合法字符和分隔字符的正則表達式,程序即能將字符串分解成標記并注明類型,下面是源碼:

    1.用于表示標記的Token類,含有文本和類型兩個屬性:
    package com.heyang.tokenmaker;

    /**
     * 標記類,內含文本及類型
     * 說明:
     * 作者:heyang(heyang78@gmail.com)
     
    */
    public class Token{
        
    // 有效內容類型
        public static final String Type_Content="Content";
        
        
    // 分隔符類型
        public static final String Type_Separator="Seperator";
        
        
    // 標記文本
        private String text;
        
        
    // 標記類型
        private String type;
        
        
    /**
         * 構造函數
         * 
    @param text
         * 
    @param type
         
    */
        
    public Token(String text,String type){
            
    this.text=text;
            
            
    if(type.equals(Type_Content) || type.equals(Type_Separator)){
                
    this.type=type;
            }
            
    else{
                
    throw new IllegalArgumentException(type+"不是有效的類型。");
            }
            
        }

        
    public String getText() {
            
    return text;
        }

        
    public String getType() {
            
    return type;
        }
    }

    2.用于分解的TokenMaker類:
    package com.heyang.tokenmaker;

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

    import org.apache.commons.lang.StringUtils;

    /**
     * 傳入一個字符串,將它轉化為記號放在鏈表中
     * 說明:
     * 作者:何楊(heyang78@gmail.com)
     
    */
    public class TokenMaker{
        
    // 來源字符串
        private String sourceString;
        
        
    // 用正則表達式表示的,表示單個有效字符的字符串,注意這個是表示合法單字字符的正則表達式
        private String validPatten;
        
        
    // 用正則表達式表示的,表示單個分隔符的字符串,注意這個是表示合法單字字符的正則表達式
        private String separatorPattern;
        
        
    // 記號鏈表
        private List<Token> tokens;
        
        
    /**
         * 構造函數
         * 
    @param sourceString
         * 
    @param validPatten
         * 
    @param seperatorPattern
         * 
    @throws Exception
         
    */
        
    public TokenMaker(String sourceString,String validPatten,String seperatorPattern) throws Exception{
            
    this.sourceString=sourceString;
            
    this.validPatten=validPatten;
            
    this.separatorPattern=seperatorPattern;
            
            findTokens(sourceString);
        }
        
        
    /**
         * 找到指定的標記并放入鏈表中
         * 
         * 說明:
         * 
    @param sourceString
         * 
    @throws Exception
         
    */
        
    private void findTokens(String sourceString)throws Exception{
            tokens
    =new ArrayList<Token>();
            
            sourceString
    =sourceString.toString();
            
    final String End = "~";// 結束標志,這個地方注意與有效文本差別化
            sourceString+=End;// 加上結束標志
            
            
    // 單詞,用來累加字符
            String word = "";
            
            
    for (int i = 0; i < sourceString.length(); i++) {
                
    // 取得每個字符
                String str = String.valueOf(sourceString.charAt(i));
                
                
    if(End.equals(str)){
                    
    // 將word放入鏈表
                    addTokenToList(new Token(word,Token.Type_Content));
                    
    break;
                }
                
                
    // 字符的驗證
                if(isValid(str)==false){
                    
    throw new Exception(""+this.sourceString+"找到非法的字符'"+str+"',無法進行求值.");
                }

                
    // 判斷是否空格
                if (StringUtils.isBlank(str)) {
                    
    if (word.trim().length() < 1) {
                        
    // 碰到空格而word中沒有字符則從頭再來
                        continue;
                    } 
    else {
                        
    // 將word放入鏈表
                        addTokenToList(new Token(word,Token.Type_Content));

                        
    // 然后吧word置空后繼續累加
                        word = "";
                    }
                } 
                
    else if(isSeparator(str)){
                    
    // 將word放入鏈表
                    addTokenToList(new Token(word,Token.Type_Content));
                    
                    
    // 將符號放入鏈表
                    addTokenToList(new Token(str,Token.Type_Separator));

                    
    // 然后吧word置空后繼續累加
                    word = "";
                }
                
    else {
                    
    // 不是則繼續累加
                    StringBuilder sb=new StringBuilder(word);
                    sb.append(str);
                    word
    =sb.toString();
                    
                    
    //word += str;
                }
            }
        }
        
        
    /**
         * 將標記添加到標記鏈表
         * 
         * 
    @param token
         
    */
        
    private void addTokenToList(Token token){
            
    if(token.getText().trim().length()>0){
                tokens.add(token);
            }
        }
        
        
    /**
         * 打印鏈表中的標記
         * 
         
    */
        
    public void printTokens(){
            System.out.println(
    "\n將文字"+sourceString+"轉化后的標記為:");
            System.out.println(
    "序號\t內容\t類型");
            System.out.println(
    "-------------------------");
            
            
    int index=1;
            
            
    for(Token token:tokens){
                System.out.println((index
    ++)+"\t"+token.getText()+"\t"+token.getType());
            }
        }
        
        
    /**
         * 判斷是否有效字符
         * 
         * 說明:
         * 
    @param str
         * 
    @return
         
    */
        
    private boolean isValid(String str){
            Pattern p 
    = Pattern.compile(validPatten,Pattern.CASE_INSENSITIVE);
            Matcher m 
    = p.matcher(str);
            
    return m.find();
        }
        
        
    /**
         * 判斷是否分隔符
         * 
         * 說明:
         * 
    @param str
         * 
    @return
         
    */
        
    private boolean isSeparator(String str) {
            Pattern p 
    = Pattern.compile(separatorPattern,Pattern.CASE_INSENSITIVE);
            Matcher m 
    = p.matcher(str);
            
    return m.find();
        }
        
        
    /**
         * 取得標記鏈表
         * 
         * 說明:
         * 
    @return
         * 創建時間:2010-6-27 上午12:46:47
         * 修改時間:2010-6-27 上午12:46:47
         
    */
        
    public List<Token> getTokens() {
            
    return tokens;
        }
        
        
    /**
         * 取得標記的內容鏈表
         * 
         * 說明:
         * 
    @return
         * 創建時間:2010-6-27 上午08:59:34
         * 修改時間:2010-6-27 上午08:59:34
         
    */
        
    public List<String> getTokenConcents(){
            List
    <String> ls=new ArrayList<String>();
            
            
    for(Token token:tokens){
                ls.add(token.getText());
            }
            
            
    return ls;
        }
        
        
    /**
         * 測試
         * 
         * 說明:
         * 
    @param args
         * 
    @throws Exception
         * 創建時間:2010-6-27 上午09:00:02
         * 修改時間:2010-6-27 上午09:00:02
         
    */
        
    public static void main(String[] args)  throws Exception{
            
    new TokenMaker("96.2+8*5-12*(4-1)/2^(3%10)","[0-9\\.+-[*]/()\\^\\%]","[+-[*]/()\\^\\%]").printTokens();
            
    new TokenMaker("select A a,b, v from ta,tb where 1=1 and 2=2 order by a asc","[\\w=<>!\\s,]","[\\s,]").printTokens();
        }
    }

    3.對算式和Sql語句分解的結果:

    將文字96.
    2+8*5-12*(4-1)/2^(3%10)轉化后的標記為:
    序號    內容    類型
    -------------------------
    1    96.2    Content
    2    +    Seperator
    3    8    Content
    4    *    Seperator
    5    5    Content
    6    -    Seperator
    7    12    Content
    8    *    Seperator
    9    (    Seperator
    10    4    Content
    11    -    Seperator
    12    1    Content
    13    )    Seperator
    14    /    Seperator
    15    2    Content
    16    ^    Seperator
    17    (    Seperator
    18    3    Content
    19    %    Seperator
    20    10    Content
    21    )    Seperator

    將文字select A a,b, v from ta,tb where 
    1=1 and 2=2 order by a asc轉化后的標記為:
    序號    內容    類型
    -------------------------
    1    select    Content
    2    A    Content
    3    a    Content
    4    ,    Seperator
    5    b    Content
    6    ,    Seperator
    7    v    Content
    8    from    Content
    9    ta    Content
    10    ,    Seperator
    11    tb    Content
    12    where    Content
    13    1=1    Content
    14    and    Content
    15    2=2    Content
    16    order    Content
    17    by    Content
    18    a    Content
    19    asc    Content

    posted on 2010-06-27 09:34 何楊 閱讀(1410) 評論(1)  編輯  收藏

    Feedback

    # re: 將字符串分解成標記的類[未登錄] 2010-06-27 20:34 feenn
    敢于嘗試很好,其實最通用的是詞法解析工具??梢钥纯碕Flex  回復  更多評論
      


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 18禁网站免费无遮挡无码中文 | 免费国产精品视频| 中文字幕亚洲码在线| 免费精品国产自产拍在| 亚洲婷婷第一狠人综合精品| 福利免费观看午夜体检区| 亚洲日本人成中文字幕| 蜜桃视频在线观看免费网址入口| 亚洲春色另类小说| 少妇高潮太爽了在线观看免费| 亚洲va在线va天堂成人| 免费精品一区二区三区在线观看| 亚洲乱码国产乱码精华| 四虎免费影院4hu永久免费| 国产亚洲蜜芽精品久久| 亚洲一区视频在线播放| 国产成人免费AV在线播放| 久久精品国产亚洲av麻豆色欲| 成人免费的性色视频| 亚洲高清一区二区三区电影| 国产人成免费视频| 国产精品极品美女自在线观看免费| 亚洲综合精品香蕉久久网| 99久久99久久免费精品小说| www.亚洲成在线| 亚洲精品国产高清嫩草影院| 永久免费A∨片在线观看| 91久久亚洲国产成人精品性色| 思思re热免费精品视频66| 亚洲AV无码之国产精品| 亚洲美女又黄又爽在线观看| 18禁美女黄网站色大片免费观看| 亚洲精品美女网站| 亚洲男人第一无码aⅴ网站| 91青青青国产在观免费影视| 亚洲日本成本人观看| 亚洲精品国产精品乱码不99| 一二三四影视在线看片免费| 五月婷婷免费视频| 亚洲性一级理论片在线观看| 亚洲а∨天堂久久精品|