2012-08-16 16 views
5

Tengo un archivo CSV (details.csv) comomaravilloso de Split CSV

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

cuando uso (Nota: Tengo otro cierre por encima de este, que lee todos los archivos CSV desde el directorio)

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() } 

en lugar de obtener el tamaño 3 que estoy recibiendo 6 con valores

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

derramado ("") es dividir los datos por coma (,) pero yo quiero que mi resultado una s

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

Cómo puedo solucionar este problema. ¡Por favor ayuda! Gracias

+0

String.split (String regex) se dividirá en cualquier expresión regular que pase allí. Como acaba de pasar "," también se está dividiendo en las comas contenidas en los valores. Necesita una expresión regular que ignore esas comas o encuentre una biblioteca Java/Groovy que analice archivos CSV. – smcg

Respuesta

20

Escribir un analizador csv es un asunto complicado.

que iba a dejar que alguien más haga el trabajo duro, y usar algo like GroovyCsv


Aquí es cómo analizar 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 
} 

que imprime:

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} 

Entonces, para obtener el campo NOMBRE de la segunda fila, puede hacer:

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

que imprime

{abc,def} 

Por supuesto, si el CSV es un archivo, puede hacerlo:

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

luego usarlo como anteriormente

+0

¡No, esta aplicación no me ayudó! – springpress

+1

@springpress ¿Por qué no? ¿Alguna explicación? –

+0

Cuando pruebo esta aplicación, de alguna manera, es como combinar mis encabezados con valores y no dar el formato que estoy buscando. Como necesito completarlo lo antes posible, he seguido el primer enfoque en mi respuesta a continuación. – springpress

0

Hay dos formas de obra. Uno está utilizando recoger

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 
} 

Aquí problema es que está eliminando las comas entre llaves ({}), es decir "{foo, bar}" se convierte en "{foo bar}" Otra forma de utilizar Java, y esto funciona muy bien

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]; 
     }       
    }  

} 

Hope this helps!

+0

Puede reescribir toda la clase Java en Groovy como 'public class CSVParser {public String [] parse (String csvLine) {def matcher = csvLine = ~ /" ([^ "] *)" | (? <=, | ^) ([^,] *) (?:, | $) /; matcher.collect {it [1]}}} ' –

+0

Y aún usaría una biblioteca de análisis CSV preescrita –

+0

Déjame probar esto y volver – springpress