it-swarm.com.de

Zeichenfolgenanalyse in Java mit Trennzeichen "\ t" unter Verwendung von "split"

Ich verarbeite eine Zeichenfolge, die durch Tabulatoren getrennt wird. Ich verwende dies mit der split-Funktion, die in den meisten Situationen funktioniert. Das Problem tritt auf, wenn ein Feld fehlt. Anstatt in diesem Feld Null zu erhalten, erhalte ich den nächsten Wert. Ich speichere die geparsten Werte in einem String-Array.

String[] columnDetail = new String[11];
columnDetail = column.split("\t");

Jede Hilfe wäre dankbar. Wenn möglich, möchte ich die analysierten Zeichenfolgen in einem String-Array speichern, damit ich leicht auf die analysierten Daten zugreifen kann.

31
lakhaman

String.split verwendet reguläre Ausdrücke , außerdem müssen Sie Ihrem Split kein zusätzliches Array zuweisen.

Die Aufteilungsmethode gibt Ihnen eine Liste. Das Problem ist, dass Sie versuchen, vorab zu definieren, wie oft eine Registerkarte vorkommt, aber wie würden Sie das wirklich wissen? Probieren Sie den Scanner oder den StringTokenizer aus und erfahren Sie, wie das Aufteilen von Strings funktioniert.

Lassen Sie mich erklären, warum\t nicht funktioniert und warum Sie \\\\ benötigen, um \\ zu entkommen.

Okay, wenn Sie Split verwenden, ist ein regulärer Ausdruck (regulärer Ausdruck) erforderlich. In einem regulären Ausdruck möchten Sie definieren, nach welchem ​​Zeichen geteilt werden soll, und wenn Sie\t schreiben, bedeutet dies nicht, dass \t und was du MÖCHST dich teilen nach ist \t, richtig? Wenn Sie also nur \t schreiben, teilen Sie Ihrem Regex-Prozessor mit, dass "Hey, aufgeteilt durch das Zeichen, das mit einem Escapezeichen versehen ist" NICHT " Hey, geteilt durch alle Charaktere, die wie \t "aussehen. Bemerken Sie den Unterschied?\Zu benutzen bedeutet, etwas zu entkommen. Und \ in Regex bedeutet etwas völlig anderes als das, was Sie denken.

Deshalb müssen Sie diese Lösung verwenden :

\\t

Damit wird der Regex-Prozessor angewiesen, nach\t zu suchen. Okay, warum brauchst du zwei von ihnen? Nun, das erste\entgeht dem zweiten, was bedeutet, dass es so aussieht:\t, wenn Sie den Text bearbeiten!

Nehmen wir nun an, Sie möchten\r\n\splitten

Na dann wärst du mit \\ geblieben, aber sieh mal, das geht nicht! weil\versucht, dem vorherigen Char zu entkommen! Aus diesem Grund soll die Ausgabe \\ sein, und Sie müssen \\\\ haben.

Ich hoffe wirklich, dass die obigen Beispiele Ihnen helfen, zu verstehen, warum Ihre Lösung nicht funktioniert und wie Sie andere erobern können!

Nun, ich habe dir das gegeben Antwort Vielleicht solltest du sie dir jetzt ansehen.

ANDERE METHODEN

StringTokenizer

Sie sollten sich das StringTokenizer ansehen, es ist ein sehr nützliches Werkzeug für diese Art von Arbeit.

Beispiel

 StringTokenizer st = new StringTokenizer("this is a test");
 while (st.hasMoreTokens()) {
     System.out.println(st.nextToken());
 }

Dies wird ausgegeben

 this
 is
 a
 test

Sie verwenden den zweiten Konstruktor für StringTokenizer, um das Trennzeichen festzulegen:

StringTokenizer(String str, String delim)

Scanner

Sie könnten auch ein Scanner verwenden, da einer der Kommentatoren sagte, dass dies ungefähr so ​​aussehen könnte

Beispiel

 String input = "1 fish 2 fish red fish blue fish";

 Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");

 System.out.println(s.nextInt());
 System.out.println(s.nextInt());
 System.out.println(s.next());
 System.out.println(s.next());

 s.close(); 

Die Ausgabe wäre

 1
 2
 red
 blue 

Das bedeutet, dass es das Wort "Fisch" ausschneidet und Ihnen den Rest gibt, wobei "Fisch" als Begrenzer verwendet wird.

Beispiele aus der Java API

84
Filip Ekberg

Versuche dies:

String[] columnDetail = column.split("\t", -1);

Lesen Sie den Javadoc unter String.split (Java.lang.String, int) , um eine Beschreibung des Grenzwert-Parameters der Split-Funktion zu erhalten:

split

public String[] split(String regex, int limit)
Splits this string around matches of the given regular expression.
The array returned by this method contains each substring of this string that is terminated by another substring that matches the given expression or is terminated by the end of the string. The substrings in the array are in the order in which they occur in this string. If the expression does not match any part of the input then the resulting array has just one element, namely this string.

The limit parameter controls the number of times the pattern is applied and therefore affects the length of the resulting array. If the limit n is greater than zero then the pattern will be applied at most n - 1 times, the array's length will be no greater than n, and the array's last entry will contain all input beyond the last matched delimiter. If n is non-positive then the pattern will be applied as many times as possible and the array can have any length. If n is zero then the pattern will be applied as many times as possible, the array can have any length, and trailing empty strings will be discarded.

The string "boo:and:foo", for example, yields the following results with these parameters:

Regex   Limit   Result
:   2   { "boo", "and:foo" }
:   5   { "boo", "and", "foo" }
:   -2  { "boo", "and", "foo" }
o   5   { "b", "", ":and:f", "", "" }
o   -2  { "b", "", ":and:f", "", "" }
o   0   { "b", "", ":and:f" }

Wenn die letzten Felder fehlen (ich Gast, das ist Ihre Situation), erhalten Sie die folgende Spalte:

field1\tfield2\tfield3\t\t

Wenn kein Limit auf split () gesetzt ist, ist das Limit 0, was dazu führt, dass "leere leere Zeichenfolgen verworfen werden". Sie können also nur 3 Felder erhalten, {"Feld1", "Feld2", "Feld3"}.

Wenn der Grenzwert auf -1 gesetzt ist, wird ein nicht positiver Wert und nachfolgende leere Zeichenfolgen nicht gelöscht. Sie können also 5 Felder erhalten, wobei die letzten beiden Zeichen eine leere Zeichenfolge sind, {"Feld1", "Feld2", "Feld3", "", ""}.

18
Happy3

Nun, niemand hat geantwortet - was zum Teil die Schuld an der Frage ist: Die Eingabezeichenfolge enthält elf Felder (auf die man schließen kann), aber wie viele Registerkarten? Möglicherweisegenau10. Dann ist die Antwort

String s = "\t2\t\t4\t5\t6\t\t8\t\t10\t";
String[] fields = s.split("\t", -1);  // in your case s.split("\t", 11) might also do
for (int i = 0; i < fields.length; ++i) {
    if ("".equals(fields[i])) fields[i] = null;
}
System.out.println(Arrays.asList(fields));
// [null, 2, null, 4, 5, 6, null, 8, null, 10, null]
// with s.split("\t") : [null, 2, null, 4, 5, 6, null, 8, null, 10]

Wenn die Felder Registerkarten enthalten, funktioniert dies natürlich nicht wie erwartet.
Das -1 bedeutet: Wende das Muster so oft an, wie es benötigt wird - so bleiben nachfolgende Felder (das elfte) erhalten (als leere Zeichenfolgen (""), falls nicht vorhanden, die explizit in null umgewandelt werden müssen).

Wenn auf der anderen Seite keine Registerkarten für die fehlenden Felder vorhanden sind, dh "5\t6" ist eine gültige Eingabezeichenfolge, die nur die Felder 5,6 enthält, gibt es keine Möglichkeit, den fields[] über die Aufteilung zu erhalten.

6
Mr_and_Mrs_D

String.split-Implementierungen unterliegen gravierenden Einschränkungen, wenn die Daten in einem durch Tabulatoren getrennten Feld selbst Zeilenumbrüche, Tabulatoren und möglicherweise "Zeichen" enthalten. 

TAB-getrennte Formate gibt es seit Jahren für Esel, aber das Format ist nicht standardisiert und variiert. Bei vielen Implementierungen werden Zeichen (Zeilenumbrüche und Registerkarten), die in einem Feld erscheinen, nicht durch Escapezeichen ersetzt. Sie folgen vielmehr den CSV-Konventionen und fassen nicht-triviale Felder in "doppelte Anführungszeichen" ein. Dann werden sie nur in doppelte Anführungszeichen gesetzt. Eine "Linie" könnte sich also über mehrere Zeilen erstrecken.

Beim Lesen hörte ich "einfach Apache-Tools wiederverwenden", was wie ein guter Ratschlag klingt. 

Am Ende habe ich persönlich opencsv gewählt. Ich fand es leicht und da es Optionen für Flucht- und Anführungszeichen bietet, sollte es die gängigsten durch Kommas und Tabulatorzeichen getrennten Datenformate abdecken.

Beispiel:

CSVReader tabFormatReader = new CSVReader(new FileReader("yourfile.tsv"), '\t');
5
Luke Usherwood

Ich hatte nur die gleiche Frage und bemerkte die Antwort in einer Art Tutorial. Im Allgemeinen müssen Sie die zweite Form der Aufteilungsmethode verwenden, indem Sie die

split(regex, limit)

Hier ist das vollständige Tutorial http://www.rgagnon.com/javadetails/Java-0438.html

Wenn Sie für den Parameter limit eine negative Zahl festlegen, werden im Array leere Zeichenfolgen angezeigt, in denen die tatsächlichen Werte fehlen. Um dies zu verwenden, sollte Ihre Anfangszeichenfolge zwei Kopien des Trennzeichens haben, d. H. Sie sollten\t\t haben, wo die Werte fehlen.

Hoffe das hilft :)

1
Ivan Marinov

Sie können yourstring.split ("\ x09"); Verwenden. Ich habe es getestet und es funktioniert.

0
RickeyShao