Java文字列分割により空の値が削除されました


286

セパレータを使用して値を分割しようとしています。しかし、私は驚くべき結果を見つけています

String data = "5|6|7||8|9||";
String[] split = data.split("\\|");
System.out.println(split.length);

8つの値を取得することを期待しています。[5,6,7、EMPTY、8,9、EMPTY、EMPTY] しかし 6つの値しか取得できません。

任意のアイデアと修正方法。EMPTY値がどこにあっても、配列になっている必要があります。

回答:


492

split(delimiter)デフォルトでは、結果の配列から末尾の空の文字列を削除します。このメカニズムをオフにするにはsplit(delimiter, limit)、次のlimitように負の値に設定したのオーバーロードバージョンを使用する必要があります。

String[] split = data.split("\\|", -1);

もう少し詳細:あなたが見つけることができるこのメソッドのドキュメントドキュメント
split(regex)内部的に返す(強調は私のものです)split(regex, 0)

limitパラメータは、パターンが適用される回数を制御し、従って、得られた配列の長さに影響を与えます。

制限nゼロより大きい場合、パターンは最大n-1回適用され、配列の長さはn以下であり、配列の最後のエントリには、最後に一致した区切り文字を超えるすべての入力が含まれます。

nない場合、パターンは可能な限り何度も適用され、配列は任意の長さにすることができます。

場合nれるゼロ、パターンが可能な回数として適用され、アレイは、任意の長さを有することができ、後続の空の文字列は破棄されます

例外

末尾の空の文字列を削除することは、そのような空の文字列が分割メカニズムによって作成された場合にのみ意味があることに言及する価値があります。したがって、"".split(anything)それ以上分割できない""ため、結果の[""]配列として取得します。
これは、分割がここで行われなかったために発生します。したがって、""空であり、末尾が元の文字列を表すにもかかわらず、分割プロセスによって作成された空の文字列ではありません。


2
ワオ。それは見事に機能しました。しかし、-1これがすべてをどのように変更するのでしょうか。
Reddy 2013年

1
あなたも試すことができますdata.split("\\|", 8)
Subhrajyoti Majumder 2013

23
split("\\|", 8)これは最初の8つのトークンに制限されるため、使用しないでください。文字列が変数の場合split("\\|", -1)は、無制限の数のトークンを作成し、最後に空のトークンを破棄しないように使用する必要があります。
ADTC 2013

2
@Reddy -1(または任意の負の数、実際には絶対値は何でもかまいません)は、splitメソッドに最後に空のトークンを保持するように指示します。デフォルトは0で、配列の最後にある空のトークンを破棄するようにメソッドに指示します。
ADTC 2013

8
どうやら、多くの人々は、末尾の空の文字列を維持することがのデフォルトの機能であると期待していましたsplit(regex)。彼らはここに行き、そうではないことに気づきました。
Attila Tanyi 2017

32

のドキュメントからString.split(String regex)

このメソッドは、指定された式とゼロの制限引数を使用して2つの引数のsplitメソッドを呼び出すかのように機能します。したがって、末尾の空の文字列は結果の配列に含まれません。

したがってString.split(String regex, int limit)、負の値を持つ2つの引数のバージョンを使用する必要があります。

String[] split = data.split("\\|",-1);

文書:

制限nがゼロより大きい場合、パターンは最大n-1回適用され、配列の長さはn以下であり、配列の最後のエントリには、最後に一致した区切り文字を超えるすべての入力が含まれます。nが正でない場合、パターンは可能な限り何度も適用され、配列は任意の長さにすることができます。nがゼロの場合、パターンは可能な限り何度も適用され、配列は任意の長さにすることができ、末尾の空の文字列は破棄されます。

これは、後続の要素を含む空の要素を除外しません。


4

以下からのstring.Split()APIのドキュメント

この文字列を、指定された正規表現の一致で分割します。このメソッドは、指定された式とゼロの制限引数を使用して2つの引数のsplitメソッドを呼び出すかのように機能します。したがって、末尾の空の文字列は結果の配列に含まれません。

オーバーロードされたString.split(regex、int)の方が適切です。


1
これは動作を説明しますが、質問には答えません。
アサイリア2013年

@assyliasが私の回答に追加しました:)
PermGenError

4

String[] split = data.split("\\|",-1);

これは常に実際の要件ではありません。上記の欠点を以下に示します。

Scenerio 1:
When all data are present:
    String data = "5|6|7||8|9|10|";
    String[] split = data.split("\\|");
    String[] splt = data.split("\\|",-1);
    System.out.println(split.length); //output: 7
    System.out.println(splt.length); //output: 8

データが欠落している場合:

Scenerio 2: Data Missing
    String data = "5|6|7||8|||";
    String[] split = data.split("\\|");
    String[] splt = data.split("\\|",-1);
    System.out.println(split.length); //output: 5
    System.out.println(splt.length); //output: 8

実際の要件は、データが欠落しているにもかかわらず長さが7であることです。データベースなどに挿入する必要がある場合があるからです。これは、以下の方法で実現できます。

    String data = "5|6|7||8|||";
    String[] split = data.split("\\|");
    String[] splt = data.replaceAll("\\|$","").split("\\|",-1);
    System.out.println(split.length); //output: 5
    System.out.println(splt.length); //output:7

ここで行ったことは、「|」を削除することです 最後にパイプし、文字列を分割します。セパレーターとして「、」がある場合、replaceAll内に「、$」を追加する必要があります。


1

空白文字、コンマ、セミコロンなどを含む複数の区切り文字を使用できます。次のように、[] +で繰り返し可能なグループの区切り文字を取得します。

 String[] tokens = "a , b,  ,c; ;d,      ".split( "[,; \t\n\r]+" );

あなたは4つのトークンを持っています-a、b、c、d

この分割を適用する前に、ソース文字列の先頭のセパレータを削除する必要があります。

質問に対する答えとして:

String data = "5|6|7||8|9||";
String[] split = data.split("[\\| \t\n\r]+");

|と一緒にセパレータとして使用する場合に備えて、空白が追加されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.