ソース コードを調べてみると、この動作の背後にある正確な問題がわかりました。
メソッドはString.split()
内部的に を使用しPattern.split()
ます。結果の配列を返す前の split メソッドは、最後に一致したインデックスをチェックするか、実際に一致するかどうかを確認します。最後に一致したインデックスが の場合、0
パターンが文字列の先頭にある空の文字列と一致したか、まったく一致しなかったことを意味します。この場合、返される配列は、同じ要素を含む単一要素の配列です。
ソースコードは次のとおりです。
public String[] split(CharSequence input, int limit) {
int index = 0;
boolean matchLimited = limit > 0;
ArrayList<String> matchList = new ArrayList<String>();
Matcher m = matcher(input);
// Add segments before each match found
while(m.find()) {
if (!matchLimited || matchList.size() < limit - 1) {
String match = input.subSequence(index, m.start()).toString();
matchList.add(match);
// Consider this assignment. For a single empty string match
// m.end() will be 0, and hence index will also be 0
index = m.end();
} else if (matchList.size() == limit - 1) { // last one
String match = input.subSequence(index,
input.length()).toString();
matchList.add(match);
index = m.end();
}
}
// If no match was found, return this
if (index == 0)
return new String[] {input.toString()};
// Rest of them is not required
上記のコードの最後の条件 -index == 0
が true の場合、単一の要素配列が入力文字列と共に返されます。
ここで、 が になる場合を考えてみましょindex
う0
。
- まったく一致しないとき。(すでにその条件の上のコメントにあるように)
一致が先頭にあり、一致した文字列の長さがの場合、ブロック内 (ループ内)0
の index の値-if
while
index = m.end();
可能な一致文字列は空の文字列(長さ = 0) のみです。ここではまさにそうです。また、それ以上一致するものはありません。一致しない場合index
は、別のインデックスに更新されます。
したがって、あなたのケースを考慮してください:
の場合d%
、最初のd
. したがって、インデックス値は になります0
。しかし、それ以上一致するものがないため、インデックス値は更新されず、if
条件は になりtrue
、元の文字列を持つ単一要素の配列を返します。
の前に 1 つ、 の前にd20+2
1 つ、2 つの一致があるためです。そのため、インデックス値が更新されるため、@Stema の回答で既に説明したように、文字列の最初の文字である区切り文字で分割された結果として空の文字列が含まれる上記のコードが返されます。d
+
ArrayList
したがって、必要な動作を取得するには (区切り文字が先頭にない場合にのみ区切り文字で分割されるため、正規表現パターンに否定的な後読みを追加できます):
"(?<!^)(?=[dk+-])" // You don't need to escape + and hyphen(when at the end)
これは、文字クラスが続く空の文字列で分割されますが、文字列の先頭は前にありません。
"ad%"
正規表現パターン -で文字列を分割する場合を考えてみましょう"a(?=[dk+-])"
。これにより、最初の要素が空の文字列である配列が得られます。ここでの唯一の変更点は、空の文字列が次のように置き換えられることa
です。
"ad%".split("a(?=[dk+-])"); // Prints - `[, d%]`
なんで?これは、一致する文字列の長さが1
. したがって、最初の一致後のインデックス値 -はbutでm.end()
はないため、単一の要素配列は返されません。0
1