2012-10-25 101 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提及番石榴的斯普利特班 –