文字列分割における空項目の扱いまとめ


StringTokenizer

StringTokenizer は、Tokenizer というトークン化の目的の通り、空項目があると無視される。

StringTokenizer st = new StringTokenizer("a,,b,c", ",");
while (st.hasMoreTokens()) {
    System.out.println(st.nextToken());
}

以下の通り。

a
b
c


String.split()

StringTokenizer とは異なり、空項目は空白として扱われる。

String[] result = "a,,b,c".split(",");
Arrays.stream(result).forEach(System.out::println);

以下の通り。

a

b
c

なので、StringTokenizerString.split() に単純置き換えすることができない。


org.apache.commons.lang3.StringUtils.split()

一方、StringUtils.split() は空項目が無視される。

Arrays.stream(StringUtils.split("a,,b,c", ","))
    .forEach(System.out::println);

以下の通り。

a
b
c


org.apache.commons.lang3.StringUtils.splitPreserveAllTokens()

空項目を扱う用途では、splitPreserveAllTokens() が用意されている。

Arrays.stream(StringUtils.splitPreserveAllTokens("a,,b,c", ",")).forEach(System.out::println);

以下の通り。

a

b
c


com.google.common.base.Splitter

Splitter のデフォルトは、String.split() と同様に空項目が扱われる。

Splitter.on(',').split("a,,b,c").forEach(System.out::println);

以下の通り。

a

b
c


omitEmptyStrings() で空項目を無視できる。

Splitter.on(',').omitEmptyStrings().split("a,,b,c").forEach(System.out::println);

以下の通り。

a
b
c


org.apache.commons.text.StringTokenizer

Commons Text の StringTokenizer はデフォルトで空項目が無視される。

StringTokenizer st = new StringTokenizer("a,,b,c", ",");
st.getTokenList().forEach(System.out::println);

以下の通り。

a
b
c


setIgnoreEmptyTokens(false) で空項目を扱うように変更できる。

StringTokenizer st = new StringTokenizer("a,,b,c", ",");
st.setIgnoreEmptyTokens(false);
st.getTokenList().forEach(System.out::println);

以下の通り。

a

b
c


まとめ

分かりにくさの原因は、StringUtils.split() が空項目を無視する仕様になっているためであろう。

それ以外は以下のように統一されている。

  • Tokenizer 系は、字句分割の意味で、空項目は無視される
  • Sprit 系は、分割を意味するために空項目は空項目として扱う