2012-08-16 9 views
5

Ho un file CSV (details.csv) comeGroovy Spalato CSV

ID,NAME,ADDRESS 
1,"{foo,bar}","{123,mainst,ny}" 
2,"{abc,def}","{124,mainst,Va}" 
3,"{pqr,xyz}","{125,mainst,IL}" 

quando uso (Nota: ho altro dispositivo di chiusura di sopra di questo che legge tutti i file CSV dalla directory)

if(file.getName().equalsIgnoreCase("deatails.csv")) { 
input = new FileInputStream(file) 
reader = new BufferedReader(new InputStreamReader(input)) 
reader.eachLine{line-> def cols = line.split(",") 
println cols.size() } 

Invece di ottenere dimensioni 3 sto ottenendo 6 con valori

1 
"{foo 
bar}" 
"{123 
mainst 
ny}" 

fuoriuscito ("") sono i dati splitting con una virgola (,), ma voglio che i miei risultati di un s

1 
"{foo,bar}" 
"{123,mainst,ny}" 

Come posso risolvere questa chiusura. Per favore aiuto! Grazie

+0

String.split (String regex) verrà diviso su qualsiasi espressione regolare si passi in là. Poiché stai passando "," si divide anche nelle virgole contenute nei valori. Hai bisogno di un'espressione regolare che ignori quelle virgole o trovi una libreria Java/Groovy che analizza i file CSV. – smcg

risposta

20

Scrivere un parser csv è un lavoro complicato.

vorrei lasciare che qualcun altro fare il lavoro duro, e usare qualcosa like GroovyCsv


Ecco come analizzare con GroovyCsv

// I'm using Grab instead of just adding the jar and its 
// dependencies to the classpath 
@Grab('com.xlson.groovycsv:groovycsv:1.0') 
import com.xlson.groovycsv.CsvParser 

def csv = '''ID,NAME,ADDRESS 
1,"{foo,bar}","{123,mainst,ny}" 
2,"{abc,def}","{124,mainst,Va}" 
3,"{pqr,xyz}","{125,mainst,IL}"''' 

def csva = CsvParser.parseCsv(csv) 
csva.each { 
    println it 
} 

che stampa:

ID: 1, NAME: {foo,bar}, ADDRESS: {123,mainst,ny} 
ID: 2, NAME: {abc,def}, ADDRESS: {124,mainst,Va} 
ID: 3, NAME: {pqr,xyz}, ADDRESS: {125,mainst,IL} 

Quindi, per ottenere il campo NOME della seconda riga, potresti fare:

def csvb = CsvParser.parseCsv(csv) 
println csvb[ 1 ].NAME 

che stampa

{abc,def} 

Naturalmente, se il CSV è un file, si può fare:

def csvc = new File('path/to/csv').withReader { 
    CsvParser.parseCsv(it) 
} 

quindi utilizzarlo come sopra

+0

no, questa API non mi ha aiutato! – springpress

+1

@springpress Perché no? Alcuna spiegazione? –

+0

Quando provo questa API, come combina le mie intestazioni con i valori e non dando il formato che sto cercando. Dal momento che ho bisogno di completare quanto prima ho seguito il primo approccio nella mia risposta di seguito. – springpress

0

Ci sono due modi di facendo. Uno sta usando raccogliere

def processCsvData(Map csvDataMap, File file) 
{ 

    InputStream inputFile = new FileInputStream(file); 
    String[] lines = inputFile.text.split('\n') 
    List<String[]> rows = lines.collect {it.split(',')} 
      // Add processing logic 
} 

Qui problema è la rimozione virgole tra parentesi ({}) cioè "{foo, bar}" diventa "{foo bar}" Un altro modo di usare Java, e questo funziona bene

public class CSVParser { 

    /* 
    * This Pattern will match on either quoted text or text between commas, including 
    * whitespace, and accounting for beginning and end of line. 
    */ 
    private final Pattern csvPattern = Pattern.compile("\"([^\"]*)\"|(?<=,|^)([^,]*)(?:,|$)"); 
    private ArrayList<String> allMatches = null;   
    private Matcher matcher = null; 
    private int size; 

    public CSVParser() {     
     allMatches = new ArrayList<String>(); 
     matcher = null; 
    } 

    public String[] parse(String csvLine) { 
     matcher = csvPattern.matcher(csvLine); 
     allMatches.clear(); 
     String match; 
     while (matcher.find()) { 
       match = matcher.group(1); 
       if (match!=null) { 
         allMatches.add(match); 
       } 
       else { 
         allMatches.add(matcher.group(2)); 
       } 
     } 

     size = allMatches.size();     
     if (size > 0) { 
       return allMatches.toArray(new String[size]); 
     } 
     else { 
       return new String[0]; 
     }       
    }  

} 

Spero che questo aiuti!

+0

È possibile riscrivere l'intera classe java in Groovy come 'public class CSVParser {public String [] parse (String csvLine) {def matcher = csvLine = ~ /" ([^ "] *)" | (? <=, | ^) ([^,] *) (?:, | $) /; matcher.collect {it [1]}}} –

+0

E utilizzerei ancora una libreria di analisi CSV pre-scritta –

+0

Fammi provare e tornare indietro – springpress

Problemi correlati