3

回答は以下を参照してください -- 士気: 決して.split()単独で電話をかけないでください。正常な動作が必要な場合は、常に長さ引数に -1 を指定してください。でも0じゃない!

javadocにPattern.split()は、次のように記載されています。

このメソッドによって返される配列には、このパターンに一致する別のサブシーケンスで終了するか、入力シーケンスの最後で終了する入力シーケンスの各部分文字列が含まれます。

このコードを目撃してください:

private static final Pattern UNDERSCORE = Pattern.compile("_");

public static void main(final String... args)
{
    System.out.println(UNDERSCORE.split("_").length);
}

ここで、javadoc を参照すると、配列には次のいずれか (引用) の入力の部分文字列が含まれている必要があります。

  • 「このパターンに一致する別のサブシーケンスによって終了する」: まあ、アンダースコアの直前の空の文字列 (UNDERSCORE明らかに一致する) があります。
  • または「入力シーケンスの最後で終了します」: アンダースコアの直後の空の文字列もあります。

それでも、上記のコードは0. なんで?これは既知のバグですか? ( imnsho はい、以下を参照してください.split()) が契約に従わない他のケースにはどのようなものがありますか? (繰り返しますが、以下を参照してください)

THE ANSWER (この説明テキストのすぐ下)

を使用する場合Pattern、引数が 1.split()つのメソッドは0、引数として引数が 2 つのメソッドを呼び出すのと同じです。

そして、ここにバグがあります。引数が 0 の場合、配列の末尾から最初の空でない要素までのすべての空の文字列が結果から削除されます。

これを読む前に、脳死状態の設計決定が何であるかを知らなかった場合は、今すぐわかります。そして、これがデフォルトの動作であることはなおさら危険です。

解決策は、メソッドの完全な形式を常に使用し.split()、負の長さの引数を与えることです。ここでは、-1 が選択されています。この場合、正常に.split()動作します。

private static final Pattern UNDERSCORE = Pattern.compile("_");

public static void main(final String... args)
{
    System.out.println(UNDERSCORE.split("_").length);
    System.out.println(UNDERSCORE.split("__").length);
    System.out.println(UNDERSCORE.split("_x_").length);
    System.out.println(UNDERSCORE.split("_", -1).length);
    System.out.println(UNDERSCORE.split("__", -1).length);
    System.out.println(UNDERSCORE.split("_x_", -1).length);
}

出力:

0 # BUG!
0 # BUG!
2 # BUG!
2 # OK
3 # OK
3 # OK
4

2 に答える 2

6

同じドキュメントから:

パラメータはlimit、パターンが適用される回数を制御するため、結果の配列の長さに影響します。

n [制限] がゼロの場合、パターンは可能な限り何度でも適用され、配列の長さは任意であり、末尾の空の文字列は破棄されます。

制限のデフォルト値は実際には次の0とおりです。

public String[] split(CharSequence input)

...

このメソッドは、指定された入力シーケンスと制限引数 0 を使用して 2 引数分割メソッドを呼び出すかのように機能します。

したがって、空の文字列は破棄されます。

必要に応じてUNDERSCORE.split("_", -1)、またはその他の負の整数を使用します。


編集:混乱を解消するために:負の制限を使用すると、返される配列は、あなたの推論によれば、次のようになります。

[ "" , "" ]

制限が正でない場合、末尾の空の文字列はすべて削除されます。最後の要素は空の文字列であるため、削除されます。次に、次のようになります。

[ "" ]

最後の要素も空の文字列であるため、これも削除されます。

つまり、末尾とは、最初の文字列の末尾ではなく、最終的な配列の末尾を指します。


以下も参照してください。

于 2013-06-04T05:03:01.643 に答える