web-dev-qa-db-fra.com

Analyse de chaîne en Java avec l'onglet "\ t" du séparateur à l'aide de la division

Je traite une chaîne délimitée par des tabulations. J'accomplis cela en utilisant la fonction split et cela fonctionne dans la plupart des situations. Le problème se produit lorsqu'un champ est manquant. Ainsi, au lieu d'obtenir la valeur null dans ce champ, j'obtiens la valeur suivante. Je stocke les valeurs analysées dans un tableau de chaînes.

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

Toute aide serait appréciée. Si possible, j'aimerais stocker les chaînes analysées dans un tableau de chaînes afin de pouvoir accéder facilement aux données analysées.

31
lakhaman

Essaye ça:

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

Lisez la Javadoc sur String.split (Java.lang.String, int) pour une explication sur le paramètre limit de la fonction split:

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" }

Lorsque les derniers champs (vous êtes invité, c'est votre cas), vous obtenez la colonne comme ceci:

field1\tfield2\tfield3\t\t

Si aucune limite n'est définie pour split (), la limite est 0, ce qui entraînera le fait que "les chaînes vides de fin seront ignorées". Ainsi, vous ne pouvez obtenir que 3 champs, {"champ1", "champ2", "champ3"}.

Lorsque la limite est définie sur -1, une valeur non positive, suivie des chaînes vides, ne sera pas ignorée. Vous pouvez donc obtenir 5 champs, les deux derniers étant des chaînes vides, {"champ1", "champ2", "champ3", "", ""}.

18
Happy3

Eh bien personne n'a répondu - ce qui est en partie la faute de la question: la chaîne d'entrée contient onze champs (cela peut être déduit) mais combien d'onglets? Très probablementexactement10. Ensuite, la réponse est

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]

Si les champs contiennent des onglets, cela ne fonctionnera évidemment pas comme prévu.
Le -1 signifie: appliquer le motif autant de fois que nécessaire - les champs de fin (le 11) seront donc conservés (sous forme de chaînes vides ("") si elles sont absentes, et doivent être explicitement transformées en null.

Par contre, s'il n'y a pas d'onglets pour les champs manquants (si "5\t6" est une chaîne de saisie valide contenant uniquement les champs 5,6), il n'existe aucun moyen d'obtenir le fields[] via split.

6
Mr_and_Mrs_D

Les implémentations de String.split auront de sérieuses limitations si les données d’un champ délimité par des tabulations contiennent elles-mêmes des caractères de nouvelle ligne, de tabulation et éventuellement ". 

Les formats délimités par la tabulation existent depuis des années, mais le format n'est pas standardisé et varie. De nombreuses implémentations n'échappent pas aux caractères (traits de soulignement et tabulations) apparaissant dans un champ. Ils suivent plutôt les conventions CSV et encapsulent les champs non triviaux entre "guillemets". Ensuite, ils échappent uniquement aux guillemets doubles. Ainsi, une "ligne" pourrait s'étendre sur plusieurs lignes.

En lisant, j'ai entendu "réutiliser simplement les outils Apache", ce qui semble être un bon conseil. 

Finalement, j'ai personnellement choisi opencsv . Je l'ai trouvé léger, et puisqu'il offre des options pour les caractères d'échappement et les guillemets, il devrait couvrir les formats de données les plus courants délimités par des virgules et des tabulations.

Exemple:

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

Vous pouvez utiliser yourstring.split ("\ x09"); Je l’ai testé et cela fonctionne.

0
RickeyShao