2008-12-29 7 views
2

Ceci est ma première question dans ce forum ... J'ai un fichier avec de nombreux champs de données (numériques et caractères) dans le fichier. Je veux délimiter le fichier avec un ensemble de longueur de délimiteur comme 2,5,1,9,6 etc.Pour ajouter des virgules dans le fichier

(Alternativement: J'ai une liste de longueurs de champs telles que 2,5,1,9,6 et je veux insérer délimiteurs virgule dans (une copie de) la chaîne de source après chaque champ)

Par exemple, si mon dossier est comme ceci:.

9483trdcvge245621jde 

alors je besoin d'insérer des virgules à 2,5,1,9,6 etc. et la sortie sera:

94,83trd,c,vge245621,jde, 

que je dois faire cela dans JAVA

S'il vous plaît aidez-moi à résoudre ce problème. Merci d'avance

+0

Quelle règle est-ce qu'il devient 94,83trd, c, vge245621, jde,? –

+0

Il veut insérer des virgules après 2 caractères, puis 5 caractères, puis 1 caractère ... etc –

+0

Heheh Par hasard travaillez-vous avec BC à Mex, ville? Ce bruit me semble tristement familier. B-) – OscarRyz

Répondre

1

Je pense que je ne comprends pas la question. Lisez le fichier, ligne par ligne, et insérez des virgules dans la chaîne.

String newString = line.substring(0, firstComma) + "," + line.substring(firstComma + 1); 

Bien sûr, cela est terriblement inefficace et peut être optimisé de nombreuses façons.

+0

Je ne sais pas exactement à quoi ressemblait la question quand vous avez répondu, mais cela ne représente pas une solution au problème. –

7
if (myString.equals("9483trdcvge245621jde")) { 
     myString = "94,83trd,c,vge245621,jde"; 
    } 

;-) blaguant

Je pense que quelque chose comme ça ...

private static final int[] pos = {2, 5, 1, 9, 6}; 
private static final String DIV = ","; 

public static String parse(String str) { 
    int start = 0; 
    StringBuilder sb = new StringBuilder(); 
    for (int i = 0; i < pos.length; i++) { 
     if (i > 0) { 
      sb.append(DIV); 
     } 
     int end = start + pos[i]; 
     if (end <= str.length()) { 
      sb.append(str.substring(start, end)); 
      start = end; 
     } else { 
      sb.append(str.substring(start)); 
     } 

    } 
    return sb.toString(); 
} 
+0

Vous pouvez supprimer le bit "if (i> 0)" en utilisant une variable (j'utilise généralement 'pad') et en tapant pad = ""; avant la boucle, et en le mettant à "," (ou DIV) à la fin de la boucle, et en incluant inconditionnellement pad dans les données ajoutées. –

1

En supposant que vous avez tous ces Strings que vous pouvez utiliser String.substring (début, fin). Ensuite, ajoutez simplement + les sous-chaînes et les virgules ensemble.

String data = "9483trdcvge245621jde"; 
String result = ""; 

result += data.substring(0,2) + ","; 
result += data.substring(2, 7) + ","; 
result += data.substring(7, 8) + ","; 

etc ...

Note: En utilisant + pour ajouter la chaîne comme celui-ci est très lent car il réaffecte et déplace les données autour de chaque fois. Il existe des moyens plus rapides de concaténer String si la vitesse est un problème.

+0

Tout bon compilateur compilera votre code à l'aide de StringBuilders dans les coulisses. En fait, je trouve '+' et '+ =' plus lisibles, donc je préfère presque toujours (en règle générale) sur StringBuilder, sauf quand je fais une concaténation à l'intérieur d'une itération. – eljenso

+0

Ne généralisent pas bien; Je ne peux voir que le premier nombre de la séquence 2,1,5,9,6 - donc il n'y a pas de généralisation évidente de votre code. –

+0

La séquence donnée a des valeurs relatives de la virgule précédente (avant l'insertion de la virgule). 0-2, 2-7, 7-8 sont les plages absolues de cette séquence. – Cogsy

3

Lire dans le fichier en tant que StringBuilder puis utilisez quelque chose comme ça

StringBuilder sb = new StringBuilder(file); //The string builder 
while (/*the string builder isn't finished*/) 
{ 
    int position = ;//The position you want the comma at 2 or 4 or whatever 
    sb.insert(position, ","); 
} 

boucle à travers autant de fois que nécessaire.

1
String newString = ""; 
int[] positions = { 2, 5, 1, 9, 6 }; //etc 
for (int i = 0; i > positions.length; i++) { 
    String tempString = ""; 
    if (i == positions.length) { //for the last item 
     tempString = oldString.substring(0, positions[i]); 
    } 
    else { //every item except the last item 
     tempString = oldString.substring(0, positions[i]) + ","; 
    } 
    oldString = oldString.substring(positions[i]); 
    newString += tempString; 
} 

Stocke les positions dans un tableau. Itérer à travers, en ajoutant les chaînes délimitées à une nouvelle chaîne et en les supprimant de l'ancienne. Ce n'est peut-être pas le meilleur moyen, mais c'est comme ça que je le ferais.: P

2

Je pense que je le ferais de cette façon

  • str étant la chaîne d'entrée
  • pos étant les longueurs des parties, après quoi nous devrions mettre une virgule

code:

public static String partition(String str, int[] pos) { 
    int oldPos = 0; 
    StringBuilder builder = new StringBuilder(str.length() + pos.length); 
    for(int len : pos) { 
     builder.append(str.substring(oldPos, oldPos+len)).append(','); 
     oldPos += len; 
    } 
    builder.append(str.substring(oldPos)).append(','); 
    return builder.toString(); 
} 
1

Voici une solution:

package com.foo; 

import java.io.BufferedReader; 
import java.io.FileReader; 
import java.io.IOException; 

public class Commafy { 

    public static final String SEPARATOR = ","; 

    private static void fail(String message) { 
     System.err.println(message); 
     System.exit(1); 
    } 

    private static int[] argsAsInts(String[] args) { 
     if (args.length < 2) { 
      fail("argument list of file name followed by field lengths is required"); 
     } 
     int[] result = new int[args.length - 1]; 
     for (int i = 1; i < args.length; ++i) { 
      try { 
       result[i - 1] = Integer.parseInt(args[i]); 
      } catch (NumberFormatException nfe) { 
       fail("can't convert argument \"" + args[i] + "\" to integer"); 
      } 
     } 
     return result; 
    } 

    private static int[] partialSums(int[] lengths) { 
     int[] result = new int[lengths.length]; 
     int start = 0; 
     for (int i = 0; i < lengths.length; ++i) { 
      result[i] = start; 
      start += lengths[i]; 
     } 
     return result; 
    } 

    private static int[] fieldsEndAt(int[] lengths, int[] starts) { 
     int[] result = new int[lengths.length]; 
     for (int i = 0; i < lengths.length; ++i) { 
      result[i] = starts[i] + lengths[i]; 
     } 
     return result; 
    } 

    private static void process(
     String fileName, int[] starts, int[] ends 
    ) throws IOException { 
     BufferedReader br = new BufferedReader(
      new FileReader(fileName) 
     ); 
     final int MIN_LENGTH = ends[ends.length - 1]; 
     String line = br.readLine(); 
     while (line != null) { 
      if (line.length() < MIN_LENGTH) { 
       System.err.println("short input line \"" + line +"\" skipped"); 
      } else { 
       StringBuilder sb = new StringBuilder(); 
       String separate = ""; 
       for (int i = 0; i < starts.length; ++i) { 
        sb.append(separate).append(line.substring(starts[i], ends[i])); 
        separate = SEPARATOR; 
       } 
       System.out.println(sb.toString()); 
      } 
      line = br.readLine(); 
     } 
     br.close(); 
    } 

    public static void main(String[] args) { 
     int[] lengths = argsAsInts(args); 
     int[] starts = partialSums(lengths); 
     int[] ends = fieldsEndAt(lengths, starts); 
     try { 
      process(args[0], starts, ends); 
     } catch (IOException e) { 
      fail("I/O Exception while processing input"); 
     } 
    } 

} 

Compte tenu d'un fichier de données nommé data/fixedlengthdata.text contenant:

9483trdcvge245621jde 
9483trdcvge245621jdelong 
9483trdcvge245621 
9483trdcvge245621jde 

et exécuter avec des arguments de:

data/fixedlengthdata.text 2 5 1 9 3 

il produit sortie:

94,83trd,c,vge245621,jde 
94,83trd,c,vge245621,jde 
short input line "9483trdcvge245621" skipped 
94,83trd,c,vge245621,jde 

(où le troisième ligne ci-dessus va à stderr, bien sûr.)

+0

Super ... Son fonctionne bien .. Merci beaucoup l'homme ..... –

0

Ceci est probablement l'exigence la plus bizzare que j'ai jamais vu, mais de toute façon ...

Psuedo code

Collection<Integer> indexes; // initialized with indexes to add commas at 
StringBuilder bldr = new StringBuilder(); 

for (int i = 0; i < inString.length(); i++){ 

    bldr.append(inString.charAt(i)); 

    if (indexes.contains(i)) 
     bldr.append(","); 

} 

return bldr.toString(); 
Questions connexes