Java StringTokenizer.nextToken()跳过空字段

时间:2012-07-10 08:22:36

标签: java string tokenize

我使用标签(/ t)作为分隔符,我知道我的数据中有一些空字段,例如:

one->two->->three

其中 - >等于标签。如您所见,空白字段仍被选项卡正确包围。 使用循环收集数据:

 while ((strLine = br.readLine()) != null) {
    StringTokenizer st = new StringTokenizer(strLine, "\t");
    String test = st.nextToken();
    ...
    }

然而,Java忽略了这个“空字符串”并跳过该字段。

有没有办法绕过这种行为并强迫java在空字段中读取?

6 个答案:

答案 0 :(得分:16)

关于此StringTokenizer问题的RFE in the Sun's bug database状态为Will not fix

对此RFE的评估表明,我引用:

  

我们在java.util.regex添加了1.4.0包   基本上已经过时了StringTokenizer的需要。我们不会删除   出于兼容性原因。但是regex可以为您提供所需的内容。

然后建议使用String#split(String)方法。

答案 1 :(得分:9)

谢谢你。由于第一个评论,我能够找到解决方案: 是的你是对的,谢谢你的参考:

 Scanner s = new Scanner(new File("data.txt"));
 while (s.hasNextLine()) {
      String line = s.nextLine();
      String[] items= line.split("\t", -1);
      System.out.println(items[5]);
      //System.out.println(Arrays.toString(cols));
 }

答案 2 :(得分:4)

您可以使用Apache Commons StringUtils.splitPreserveAllTokens()。它完全符合您的需求。

答案 3 :(得分:1)

我会使用Guava's Splitter,它不需要所有大型正则表达式机制,并且比String的split()方法表现得更好:

Iterable<String> parts = Splitter.on('\t').split(string);

答案 4 :(得分:0)

正如您在Java文档http://docs.oracle.com/javase/6/docs/api/java/util/StringTokenizer.html中所看到的,您可以将构造函数public StringTokenizer(String str, String delim, boolean returnDelims)returnDelims true

一起使用

因此它将每个分隔符作为单独的字符串返回!

修改

不要 使用这种方式,因为@npe已经输出,不应再使用StringTokenizer了!请参阅JavaDoc:

  

StringTokenizer是一个遗留类,为保持兼容性而保留   原因虽然在新代码中不鼓励使用 。建议   任何寻求此功能的人都使用split的{​​strong> String 方法   或改为java.util.regex包。

答案 5 :(得分:0)

public class TestStringTokenStrict {

/**
 * Strict implementation of StringTokenizer
 * 
 * @param str
 * @param delim
 * @param strict
 *            true = include NULL Token
 * @return
 */
static StringTokenizer getStringTokenizerStrict(String str, String delim, boolean strict) {
    StringTokenizer st = new StringTokenizer(str, delim, strict);
    StringBuffer sb = new StringBuffer();

    while (st.hasMoreTokens()) {
        String s = st.nextToken();
        if (s.equals(delim)) {
            sb.append(" ").append(delim);
        } else {
            sb.append(s).append(delim);
            if (st.hasMoreTokens())
                st.nextToken();
        }
    }
    return (new StringTokenizer(sb.toString(), delim));
}

static void altStringTokenizer(StringTokenizer st) {
    while (st.hasMoreTokens()) {
        String type = st.nextToken();
        String one = st.nextToken();
        String two = st.nextToken();
        String three = st.nextToken();
        String four = st.nextToken();
        String five = st.nextToken();

        System.out.println(
                "[" + type + "] [" + one + "] [" + two + "] [" + three + "] [" + four + "] [" + five + "]");
    }
}

public static void main(String[] args) {
    String input = "Record|One||Three||Five";
    altStringTokenizer(getStringTokenizerStrict(input, "|", true));
}}