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のバグデータベースには、ステータスが付いたこのStringTokenizer問題に関するRFEがありますWill 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のSplittersplit()を使用します。これは、すべての大きな正規表現の機械を必要とせず、Stringの方法よりも適切に動作します。

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 に答える