空の文字列で分割すると、サイズ1の配列が返されます。
scala> "".split(',')
res1: Array[String] = Array("")
これは空の配列を返すと考えてください:
scala> ",,,,".split(',')
res2: Array[String] = Array()
説明してください :)
同じ理由で
",test" split ','
そして
",test," split ','
サイズ2の配列を返します。最初の一致の前のすべてが最初の要素として返されます。
オレンジをゼロ回分割すると、ちょうど1つのピース、つまりオレンジができます。
空の文字列を分割すると、空の文字列が最初の要素として返されます。ターゲット文字列に区切り文字が見つからない場合、元の文字列が空であっても、元の文字列を保持しているサイズ1の配列を取得します。
JavaおよびScala splitメソッドは、次のような2つのステップで動作します。
",,,".split(",")
が空の配列を返す理由です。これによれば、"".split(",")
の結果は、2番目のステップのために空の配列になるはずですよね?
そうすべき。残念ながら、これは人為的に導入されたコーナーケースです。そしてそれは悪いことですが、少なくともは文書化されていますJava.util.regex.Pattern
で、覚えていればドキュメントを見てください:
N == 0の場合、結果はn <0の場合と同じですが、末尾の空の文字列は返されません。 (上で説明したように、入力自体が空の文字列である場合は特別であり、limitパラメータは適用されないことに注意してください。)
ですから、あなたが達成したいことを明確に知らない限り/空の文字列があなたのプログラムのようなものではないことが確実でない限り、常に2番目のパラメータとしてn == -1
を渡すことをお勧めします。入力として取得します。
プロジェクトですでにGuavaを使用している場合は、 Splitter(documentation) クラスを試すことができます。非常に豊富なAPIを備えており、コードを非常に理解しやすくしています。
Splitter.on(".").split(".a.b.c.") // "", "a", "b", "c", ""
Splitter.on(",").omitEmptyStrings().split("a,,b,,c") // "a", "b", "c"
Splitter.on(CharMatcher.anyOf(",.")).split("a,b.c") // "a", "b", "c"
Splitter.onPattern("=>?").split("a=b=>c") // "a", "b", "c"
Splitter.on(",").limit(2).split("a,b,c") // "a", "b,c"
"a".split(",")
-> _"a"
_したがって、"".split(",")
-> _""
_
すべてのプログラミング言語では、空の文字列が依然として有効な文字列であることを知っています。したがって、区切り文字を使用して分割を行うと、その要素が空の文字列である単一の要素配列が常に返されます。 null(空白ではない)文字列の場合、別の問題になります。
この split
の動作は、良くも悪くも、Javaから継承されます...
Scalaは、String
プリミティブの定義をオーバーライドしません。
Limitパラメーターは、パターンが適用される回数を制御するため、結果の配列の長さに影響します。制限nがゼロより大きい場合、パターンは最大n-1回適用され、配列の長さはn以下になり、配列の最後のエントリには最後に一致した区切り文字を超えるすべての入力が含まれます。 nが正でない場合、パターンはできるだけ多く適用され、配列の長さは任意です。 nがゼロの場合、パターンはできるだけ多く適用されます。配列の長さは任意で、末尾の空の文字列は破棄されます。
つまり、limit=-1
(すべて?)他の言語の動作を取得するには:
@ ",a,,b,,".split(",")
res1: Array[String] = Array("", "a", "", "b")
@ ",a,,b,,".split(",", -1) // limit=-1
res2: Array[String] = Array("", "a", "", "b", "", "")
Java動作は かなり紛らわしい ですが、:
上記の動作は、少なくともJava 5からJava 8。
JDK-655959 で空の文字列を分割するときに、空の配列を返すように動作を変更しようとしました。ただし、さまざまな場所でリグレッションが発生すると、すぐに JDK-8028321 に戻りました。変更により、最初のJava 8リリースになりません。
注:splitメソッドはJavaの最初からではありません( 1.0.2ではない )ですが、実際にはあります)少なくとも1.4から(例: JSR51 2002年頃)。私はまだ調査中です...
不明なのは、なぜJavaが最初にこれを選んだか(これはもともと「エッジケース」の監視/バグだったのではないかと疑っています)が、今では取り返しのつかないほど言語に焼き付けられているためです- 残り 。
空の文字列は、文字列の分割中に特別なステータスを持ちません。以下を使用できます。
Some(str)
.filter(_ != "")
.map(_.split(","))
.getOrElse(Array())