15

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

one->two->->three

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

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

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

有没有办法规避这种行为并强制java读取空字段?

4

6 回答 6

16

Sun 的错误数据库中有一个关于此问题的 RFE,其状态StringTokenizerWill not fix.

对此 RFE 的评估指出,我引用:

随着java.util.regex包的加入1.4.0,我们基本淘汰了对StringTokenizer. 出于兼容性原因,我们不会删除该类。但regex只为您提供所需的东西。

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

于 2012-07-10T08:27:11.933 回答
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));
 }
于 2012-07-10T11:15:41.907 回答
5

您可以使用ApacheCommons StringUtils.splitPreserveAllTokens()。它完全符合您的需要。

于 2012-07-10T08:26:23.993 回答
1

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

Iterable<String> parts = Splitter.on('\t').split(string);
于 2012-07-10T08:30:32.767 回答
0

正如您在 Java Doc 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方法Stringjava.util.regex包来代替。

于 2012-07-10T08:26:20.407 回答
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));
}}
于 2020-05-07T08:36:55.953 回答