2012-10-25 113 views
4

我不知道爲什麼我這麼苦苦掙扎,但任何幫助將不勝感激。Java Tokenizer,分隔字符串

我正在創建自己的標記器,它接收帶有命令,分隔符和值列表的文件。然後它輸出每個「標記」以及它是什麼類型。

輸入:AND 3, 4, 5 ; some comments

我需要輸出:

AND --- command 
3 --- value 
, --- delimiter 
4 --- value 
, --- delimiter 
5 --- value 

我現在它的工作的地方,我輸出:

AND 3, 4, 5 --- delimiter 

,但我需要進一步打破它。

這裏就是我在目前:

ArrayList<Token> tokenize(String[] input) { 
    ArrayList<Token> tokens = new ArrayList<Token>(); 
    for (String str : input) { 
     Token token = new Token(str.trim()); 
     //Check if int 
     try{ 
      Integer.parseInt(str); 
      token.type = "number"; 
     } catch(NumberFormatException e) { 

     } 
     if (token.type == null) { 
      if (commands.contains(str)) 
       token.type = "command"; 
      else if (str.contains(",")) { 
       token.type = "delimiter"; 
      } else if (destValues.contains(str)) 
       token.type = "destination"; 
      else 
       token.type = "unknown"; 
     } 

     if(! token.type.equals("unknown")) 
      tokens.add(token); 
    } 
    return tokens; 
} 

只有真正的限制,我有這個任務不能夠使用的StringTokenizer和正則表達式。

+0

你可以使用String.split(),或者你需要手動標記你的字符串嗎? – davidbuzatto

+0

我能夠使用split(),但是我怎樣才能拆分它來擺脫空間,但保留逗號? – btjordan23

+0

您的輸入是否已被分割?你想改善什麼? – davidbuzatto

回答

2

它似乎是你的輸入是不正確的。試試這個來分割輸入,然後使用你的tokenize方法。

import java.util.*; 

public class Foo { 

    public static void main(String[] args) { 


     String input = "AND 3, 4, 5 ; some comments"; 
     List<String> parts = new ArrayList<String>(); 

     // removing comments 
     input = input.split(";")[0]; 

     // splits using spaces 
     String[] firstPass = input.trim().split(" "); 

     for (String s : firstPass) { 

      // the current part cannot be empty 
      if (!s.trim().isEmpty()) { 

       // splits using comma 
       String[] secondPass = s.split(","); 

       for (String ss : secondPass) { 
        parts.add(ss.replace(",", "")); 
       } 

       // verifies if the current part has a comma 
       // and if so, inserts it as a part 
       if (s.contains(",")) { 
        parts.add(","); 
       } 

      } 

     } 

     for (String a : parts) { 
      System.out.println(a); 
     } 

    } 

} 

編輯:由於我的第一個工作前面回答,這裏是一些refactors一個完整的例子...

import java.util.*; 

public class MyTinyParser { 

    private static final String COMMANDS = "AND OR FOO BAR"; 

    private List<String> extract(String input) { 

     List<String> parts = new ArrayList<String>(); 

     // removing comments 
     input = input.split(";")[0]; 

     // splits using spaces 
     String[] firstPass = input.trim().split(" "); 

     for (String s : firstPass) { 

      // the current part cannot be empty 
      if (!s.trim().isEmpty()) { 

       // splits using comma 
       String[] secondPass = s.split(","); 

       for (String ss : secondPass) { 
        parts.add(ss.replace(",", "")); 
       } 

       // verifies if the current part has a comma 
       // and if so, inserts it as a part 
       if (s.contains(",")) { 
        parts.add(","); 
       } 

      } 

     } 

     return parts; 

    } 

    public List<Token> tokenize(String input) { 

     List<Token> tokens = new ArrayList<Token>(); 

     for (String str : extract(input)) { 

      Token token = new Token(str); 

      // check if int 
      try{ 
       Integer.parseInt(str); 
       token.type = "number"; 
      } catch(NumberFormatException e) { 
      } 

      if (token.type == null) { 

       if (COMMANDS.contains(str)){ 
        token.type = "command"; 
       } else if (str.contains(",")) { 
        token.type = "delimiter"; 
       } else { 
        token.type = "unknown"; 
       } 

      } 

      if(!token.type.equals("unknown")) { 
       tokens.add(token); 
      } 

     } 

     return tokens; 

    } 

    private class Token { 

     String value; 
     String type; 

     Token(String value) { 
      this.value = value; 
     } 

     @Override 
     public String toString() { 
      return String.format("Token[%s, %s]", value, type); 
     } 

    } 

    public static void main(String[] args) { 

     MyTinyParser mtp = new MyTinyParser(); 
     List<Token> tokens = mtp.tokenize("AND 3, 4, 5 ; some comments"); 

     for (Token t : tokens) { 
      System.out.println(t); 
     } 

    } 

} 
+0

非常感謝你!它做到了!感謝你的幫助。 – btjordan23

+0

@ btjordan23不客氣!我正在改進我的例子...等一下。 – davidbuzatto

+0

+1完整解決方案 – Watt

2

如果你被允許使用谷歌的API,你也可以嘗試類似的東西到下面。

import com.google.common.base.Splitter; 

public class Tmp { 

    public static void main(String[] args) { 
     String str = "AND 3, 4, 5 ; some comments"; 

     Iterable<String> stringIterable = Splitter.on(' ').trimResults() 
       .omitEmptyStrings() 
       .split(str); 

     for (String str1 : stringIterable) { 
      int commaIndex = str1.indexOf(","); 
      if (commaIndex > 0) { 
       System.out.println(str1.subSequence(0, commaIndex)); 
       System.out.println(","); 
      } else { 
       System.out.println(str1); 
      } 
     } 


    } 

} 

它打印

AND 
3 
, 
4 
, 
5 
; 
some 
comments 

附:不是最好的代碼。它可以得到進一步改善,人們感到自由請請進來。

+0

+1提及番石榴的斯普利特班 –