wake-up-neo.net

Bei der Java-Zeichenfolge wurden leere Werte entfernt

Ich versuche, den Wert mit einem Trennzeichen aufzuteilen. Aber ich finde die überraschenden Ergebnisse

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

Ich erwarte, 8 Werte zu erhalten. [5,6,7, LEER, 8,9, LEER, LEER] Aber ich bekomme nur 6 Werte.

Irgendeine Idee und wie man repariert. Unabhängig davon, ob der Wert LEER an einem anderen Ort ist, sollte er im Array liegen.

222
Reddy

split(delimiter) entfernt standardmäßig leere Zeichenfolgen aus dem Ergebnis-Array. Um diesen Mechanismus zu deaktivieren, müssen Sie eine überladene Version von split(delimiter, limit) verwenden, wobei limit auf einen negativen Wert gesetzt ist

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

Etwas mehr Details:
split(regex) gibt intern das Ergebnis von split(regex, 0) zurück und in Dokumentation dieser Methode finden Sie (Hervorhebung meines).

Der Parameter limit steuert, wie oft das Muster angewendet wird, und wirkt sich daher auf die Länge des resultierenden Arrays aus. 

Wenn die Grenze ngrößer als null ist, wird das Muster höchstens n - 1 mal angewendet, die Länge des Arrays ist nicht größer als n, und der letzte Eintrag des Arrays enthält alle Eingaben, die über den letzten übereinstimmenden Begrenzer hinausgehen. 

Wenn nnicht positiv ist, wird das Muster so oft wie möglich angewendet und das Array kann eine beliebige Länge haben. 

Wenn nzero ist, wird das Muster so oft wie möglich angewendet, das Array kann beliebig lang sein und nachfolgende leere Zeichenfolgen werden verworfen.

Ausnahme:

Es ist erwähnenswert, dass das Entfernen der folgenden leeren Zeichenfolge nur dann sinnvoll ist, wenn solche leeren Zeichenfolgen durch den Split-Mechanismus erstellt wurden. Für "".split(anything), da wir "" nicht aufteilen können, erhalten wir als Ergebnis [""] array.
Dies geschieht, weil die Aufteilung hier nicht stattfand, also "", obwohl leer und nachgestellt, ursprüngliche Zeichenfolge und keine leere Zeichenfolge, die durch Aufteilen des Prozesses erstellt wurde.

390
jlordo

Aus der Dokumentation von String.split(String regex) :

Diese Methode funktioniert so, als würde sie die Split-Methode mit zwei Argumenten mit dem angegebenen Ausdruck und einem Grenzwert-Argument von Null aufrufen. Nachgestellte leere Zeichenfolgen sind daher nicht im resultierenden Array enthalten. 

Sie müssen also die beiden Argumentversionen String.split(String regex, int limit) mit einem negativen Wert verwenden:

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

Doc:

Wenn der Grenzwert n größer als Null ist, wird das Muster höchstens n - 1 mal angewendet, die Länge des Arrays ist nicht größer als n und der letzte Eintrag des Arrays enthält alle Eingaben, die über den letzten übereinstimmenden Begrenzer hinausgehen. Wenn n nicht positiv ist, wird das Muster so oft wie möglich angewendet und das Array kann eine beliebige Länge haben. Wenn n gleich Null ist, wird das Muster so oft wie möglich angewendet, das Array kann beliebig lang sein und nachfolgende leere Zeichenfolgen werden verworfen.

Dadurch werden keine leeren Elemente, einschließlich der nachfolgenden, ausgelassen.

31
ppeterka

Aus String.split () API Doc :

Teilt diese Zeichenfolge um Übereinstimmungen mit dem angegebenen regulären Ausdruck . Diese Methode funktioniert so, als würde sie die Split-Methode mit zwei Argumenten mit .__ aufrufen. der angegebene Ausdruck und ein Limit-Argument von Null. Nachlauf leer Zeichenfolgen sind daher nicht im resultierenden Array enthalten.

Überladenes String.split (Regex, int) ist für Ihren Fall besser geeignet.

4
PermGenError

Eine andere Option ist die Verwendung von Guavas Splitter. Es hat nicht den Aufwand eines regulären Ausdrucks (den Sie in diesem Fall nicht benötigen) und löscht standardmäßig keine leeren nachfolgenden Zeichenfolgen. 

Zum Beispiel:

 String data = "5|6|7||8|9||";
 Iterable<String> results = Splitter.on('|').split(data);
 // convert to array
 String[] asArray = Iterables.toArray(results, String.class);

Weitere Informationen finden Sie im Wiki: https://github.com/google/guava/wiki/StringsExplained

3
nickool

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

Dies ist nicht immer die eigentliche Anforderung. Der Nachteil von oben ist unten gezeigt:

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

Wenn Daten fehlen:

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

Die tatsächliche Anforderung ist, dass die Länge 7 sein sollte, obwohl Daten fehlen. Weil es Fälle gibt, in denen ich etwas in die Datenbank einfügen muss oder so. Dies können wir mit dem folgenden Ansatz erreichen.

    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

Was ich hier gemacht habe ist, ich entferne "|" Pipe am Ende und dann die Zeichenfolge aufteilen. Wenn Sie "," als Trennzeichen haben, müssen Sie ", $" in replaceAll einfügen.

2

möglicherweise haben Sie mehrere Trennzeichen, einschließlich Leerzeichen, Kommas, Semikolons usw. Nehmen Sie diese in wiederholbarer Gruppe mit [] +, wie:

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

sie haben 4 Token - a, b, c, d

führende Trennzeichen in der Quellzeichenfolge müssen entfernt werden, bevor diese Aufteilung angewendet wird.

als Antwort auf die gestellte Frage:

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

leerzeichen werden nur für den Fall hinzugefügt, dass Sie diese als Trennzeichen zusammen mit | haben

1