【问题标题】:Java CSVReader ignore commas in double quotesJava CSVReader 忽略双引号中的逗号
【发布时间】:2015-10-23 12:24:31
【问题描述】:

我有一个无法解析的 CSV 文件。我正在使用opencsv 库。这是我的数据的样子以及我想要实现的目标。

RPT_PE,CLASS,RPT_MKT,PROV_CTRCT,CENTER_NM,GK_TY,MBR_NM,MBR_PID "20150801","NULL","33612","00083249P PCP602","JOE SMITH ARNP","NULL","FRANK, LUCAS E","50004655200"

我遇到的问题是成员名称 ("FRANK, LUCAS E") 被分成两列,并且成员名称应该是一列。我再次使用 opencsv 和逗号作为分隔符。有什么办法可以忽略双引号内的逗号?

        public void loadCSV(String csvFile, String tableName,
            boolean truncateBeforeLoad) throws Exception {

        CSVReader csvReader = null;
        if (null == this.connection) {
            throw new Exception("Not a valid connection.");
        }
        try {

            csvReader = new CSVReader(new FileReader(csvFile), this.seprator);

        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("Error occured while executing file. "
                    + e.getMessage());
        }
        String[] headerRow = csvReader.readNext();

        if (null == headerRow) {
            throw new FileNotFoundException(
                    "No columns defined in given CSV file."
                    + "Please check the CSV file format.");
        }

        String questionmarks = StringUtils.repeat("?,", headerRow.length);
        questionmarks = (String) questionmarks.subSequence(0, questionmarks
                .length() - 1);

        String query = SQL_INSERT.replaceFirst(TABLE_REGEX, tableName);
        System.out.println("Base Query: " + query);
        String headerRowMod = Arrays.toString(headerRow).replaceAll(", ]", "]");
        String[] strArray = headerRowMod.split(",");

        query = query
                .replaceFirst(KEYS_REGEX, StringUtils.join(strArray, ","));

        System.out.println("Add Headers: " + query);
        query = query.replaceFirst(VALUES_REGEX, questionmarks);
        System.out.println("Add questionmarks: " + query);

        String[] nextLine;
        Connection con = null;
        PreparedStatement ps = null;
        try {
            con = this.connection;
            con.setAutoCommit(false);
            ps = con.prepareStatement(query);

            if (truncateBeforeLoad) {
                //delete data from table before loading csv
                con.createStatement().execute("DELETE FROM " + tableName);
            }

            final int batchSize = 1000;
            int count = 0;
            Date date = null;
            while ((nextLine = csvReader.readNext()) != null) {
                System.out.println("Next Line: " + Arrays.toString(nextLine));
                if (null != nextLine) {
                    int index = 1;
                    for (String string : nextLine) {
                        date = DateUtil.convertToDate(string);
                        if (null != date) {
                            ps.setDate(index++, new java.sql.Date(date
                                    .getTime()));
                        } else {
                            ps.setString(index++, string);
                        }
                    }
                    ps.addBatch();
                }
                if (++count % batchSize == 0) {
                    ps.executeBatch();
                }
            }
            ps.executeBatch(); // insert remaining records
            con.commit();
        } catch (SQLException | IOException e) {
            con.rollback();
            e.printStackTrace();
            throw new Exception(
                    "Error occured while loading data from file to database."
                    + e.getMessage());
        } finally {
            if (null != ps) {
                ps.close();
            }
            if (null != con) {
                con.close();
            }
            csvReader.close();
        }
    }

    public char getSeprator() {
        return seprator;
    }

    public void setSeprator(char seprator) {
        this.seprator = seprator;
    }

    public char getQuoteChar() {
        return quoteChar;
    }

    public void setQuoteChar(char quoteChar) {
        this.quoteChar = quoteChar;
    }
}

【问题讨论】:

  • 根据 CSVReader 文档,应该处理这种情况。发布代码的关键部分。
  • 查看我的代码示例。
  • 我写了一个简单的程序,它似乎对我有用。而不是额外的列,我得到了带有逗号的全名,这是预期的。你可以试试,它可能会提供一些线索

标签: java csv delimiter opencsv


【解决方案1】:

您是否尝试过以下操作?

CSVReader reader = new CSVReader(new FileReader("yourfile.csv"), ',');

我编写了以下程序,它对我有用,我得到了以下结果:

[20150801] [NULL] [33612] [00083249P PCP602] [JOE SMITH ARNP] [NULL] [弗兰克,卢卡斯 E] [50004655200]

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import au.com.bytecode.opencsv.CSVReader;

public class CVSTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        CSVReader reader = null;
        try {

            reader = new CSVReader(new FileReader(
                    "C:/Work/Dev/Projects/Pure_Test/Test/src/cvs"), ',');
        } catch (FileNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        String[] nextLine;
        try {
            while ((nextLine = reader.readNext()) != null) {
                // nextLine[] is an array of values from the line
                System.out.println("[" + nextLine[0] + "] [" + nextLine[1]
                        + "] [" + nextLine[2] + "] [" + nextLine[3] + "] ["
                        + nextLine[4] + "] [" + nextLine[5] + "] ["
                        + nextLine[6] + "] [" + nextLine[7] + "]");
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

【讨论】:

  • 这不起作用,因为 csvreader 正在寻找一个字符,而不是一个字符串。
【解决方案2】:

根据文档,您可以在构造函数中提供自定义分隔符和引号字符,这应该处理它:

CSVReader(Reader reader, char separator, char quotechar)

用 , 作为分隔符和 " 作为引号字符来构建你的阅读器。

【讨论】:

  • 我试过了,它仍然把名字分成两个列。
【解决方案3】:

将 CSV 作为 SQL 表加载到 HSQLDB 中很简单,然后从表中选择行插入到另一个数据库中。 HSQLDB 处理引号内的逗号。您需要将文本源定义为“引用”。看到这个:

http://hsqldb.org/doc/2.0/guide/texttables-chapt.html

【讨论】:

    【解决方案4】:

    您的案例应开箱即用,无需特殊配置。

    如果你不能让它工作,那么只需切换到uniVocity-parsers 为你做这件事 - 与 OpenCSV 相比,它的速度是 OpenCSV 的两倍,需要的代码少得多,而且功能丰富。

    CsvParserSettings settings = new CsvParserSettings();     // you have many configuration options here - check the tutorial.
    
    CsvParser parser = new CsvParser(settings);
    
    List<String[]> allRows = parser.parseAll(new FileReader(new File("C:/Work/Dev/Projects/Pure_Test/Test/src/cvs")));
    

    披露:我是这个库的作者。它是开源免费的(Apache V2.0 许可)。

    【讨论】:

      猜你喜欢
      • 2017-08-08
      • 1970-01-01
      • 2014-02-26
      • 1970-01-01
      • 1970-01-01
      • 2019-07-05
      • 2013-04-02
      • 2013-10-14
      相关资源
      最近更新 更多