2012-08-16 66 views
5

我有一个csv文件(details.csv)像Groovy的拆分CSV

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

当我使用(注:我有其他封闭上述这里面读取目录中所有CSV文件)

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

非但没有大小3我与价值观得到6

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

泻(“”)是由逗号分割数据(,),但我想我的结果s

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

我该如何解决这个问题。请帮忙!谢谢

+0

String.split(String regex)会在你传入的任何正则表达式中分割。既然你只是传递“,”它也分裂在值中包含的逗号。您需要一个忽略这些逗号的正则表达式,或者找到解析CSV文件的Java/Groovy库。 – smcg 2012-08-16 20:54:19

回答

20

编写csv解析器是一件棘手的事情。

我先给别人做的辛勤工作,以及使用的东西like GroovyCsv


这里是如何与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 
} 

它打印解析它:

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} 

因此,要获得第二行的NAME字段,您可以这样做:

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

它打印

{abc,def} 

当然,如果CSV是一个文件,你可以这样做:

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

然后用它作为上述

+0

nope这个api没有帮助我! – springpress 2012-08-17 14:44:51

+1

@springpress为什么不呢?任何解释? – 2012-08-17 14:47:57

+0

当我尝试这个api时,它是如何将我的头文件与值相结合,而不是以我期待的格式给出。因为我需要尽快完成,所以我在下面的答案中遵循了第一种方法。 – springpress 2012-08-17 16:49:38

0

有两种方式这样做。 一种是使用收集

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 
} 

这里的问题是它是在括号({})之间即除去逗号“{FOO,酒吧}”变成“{FOO栏}” 用java的另一种方式,这工作就好了

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

} 

希望这有助于!

+0

您可以在Groovy中将整个java类重写为'public class CSVParser {public String [] parse(String csvLine){def matcher = csvLine =〜/“([^”] *)“|(?<=,|^)([^,] *)(?:,| $)/; matcher.collect {it [1]}}}' – 2012-08-17 15:04:28

+0

我仍然会使用预先编写的CSV解析库 – 2012-08-17 15:06:21

+0

让我试试这个并取回 – springpress 2012-08-17 16:50:26