CSV解析器,CSV解释器,新媒传信上机题,新媒传信面试,java解析csv
2016-04-26 15:19
603 查看
原题:
更复杂点的CSV文本:
"o""reily","""orange,lime""",2008-09-01,",,nil""""",1980-e09
循环解题:
递归解题:
比较高效的解法:
正则解题:
百度搜“CSV解析器”,答案很多。
更复杂点的CSV文本:
"o""reily","""orange,lime""",2008-09-01,",,nil""""",1980-e09
循环解题:
public static void parseCsv(String sourceLine) { if (null == sourceLine) { System.err.println("Source text is null!"); return; } String[] cells = sourceLine.split(","); for (int i = 0; i < cells.length; i++) { // 确保没有null的字符串 String cell = cells[i]; if (null == cell) { cell = ""; } // 计算“"”个数 int len = cell.length(); int num = 0; for (int j = 0; j < len; j++) { if (cell.charAt(j) == '\"') { num++; } } // 如果“"”个数为偶数,则CSV字段完整,否则CSV字段不完整 if (num % 2 == 0) { // 删除首尾的“"” if (cell.startsWith("\"") && cell.endsWith("\"") && cell.length() > 1) { cell = cell.substring(1, cell.length() - 1); } cell = cell.replaceAll("\"\"", "\""); System.out.println(cell); } else { // cell不完整,并且是最后一个cell,则非法的csv格式 if (i == cells.length - 1) { System.err.println("Illegal csv text!"); return; } // 将不完整的cell拼接到下一个cell int nextIndex = i + 1; cells[nextIndex] = cells[i] + "," + cells[nextIndex]; } } }
递归解题:
public static void parseCsvRecursively(String sourceLine) { if (sourceLine == null) { System.err.println("Source text is null!"); return; } if (sourceLine.contains(",")) { // 包含“,”,遍历所有字符 StringBuilder sourceBuf = new StringBuilder(sourceLine); int length = sourceBuf.length(); // 双引号个数 int doubleQuotesCount = 0; for (int i = 0; i < length; i++) { char c = sourceBuf.charAt(i); if (c == '\"') { doubleQuotesCount++; } else if (c == ',') { // 双引号个数为偶数,表示截止索引i之前的字符串为完整CSV字段,循环结束 if (doubleQuotesCount % 2 == 0) { // 解析打印i之前的完整CSV字段 parseAndPrintCell(sourceBuf.substring(0, i)); // 如果i后面还有字符串,递归处理余下的CSV字符串 if (i < length - 1) { parseCsvRecursively(sourceBuf.substring(i + 1)); } break; } } } } else { // 不包含“,”,一个独立的CSV字段 parseAndPrintCell(sourceLine); } } private static void parseAndPrintCell(String cell) { if (cell == null) { return; } StringBuilder cellBuf = new StringBuilder(cell); // 删除首尾“"” if (cellBuf.length() > 1 && cellBuf.charAt(0) == '\"' && cellBuf.charAt(cellBuf.length() - 1) == '\"') { cellBuf.deleteCharAt(cellBuf.length() - 1); cellBuf.deleteCharAt(0); } // 两个双引号替换成一个 int twoQuotesIndex, // 双引号的位置 fromIndex = 0;// 查找双引号的起始位置 while ((twoQuotesIndex = cellBuf.indexOf("\"\"", fromIndex)) > -1) { // 两个双引号,删除一个 cellBuf.deleteCharAt(twoQuotesIndex); // 下次循环,从当前双引号的后面位置开始查找 fromIndex = twoQuotesIndex + 1; // 如果位置超出字符串,停止循环 if (fromIndex >= cellBuf.length()) { break; } } System.out.println(cellBuf); }
比较高效的解法:
public static void parseCsv(String sourceLine) { if (null == sourceLine) { System.err.println("Source text is null!"); return; } StringBuilder sourceBuf = new StringBuilder(sourceLine); StringBuilder cellBuf = new StringBuilder(); int length = sourceBuf.length(); int dubbleQuotesCount = 0; for (int i = 0; i < length; i++) { char c = sourceBuf.charAt(i); if (c == ',') { // 如果双引号个数为偶数,则CSV字段完整,否则CSV字段不完整 if (dubbleQuotesCount % 2 == 0) { parseAndPrintCell(cellBuf); cellBuf.set 4000 Length(0); } else { cellBuf.append(c); } } else { // 双引号计数 if (c == '\"') { dubbleQuotesCount++; } // 除了逗号,其他字符全部放入CellBuffer cellBuf.append(c); // 处理最后一个不是以逗号结尾CSV字段 if (i >= length - 1) { if (dubbleQuotesCount % 2 == 0) { parseAndPrintCell(cellBuf); cellBuf.setLength(0); } else { System.err.println("Illegal csv text!"); } } } } } private static void parseAndPrintCell(StringBuilder cellBuf) { // 删除首尾“"” if (cellBuf.length() > 1 && cellBuf.charAt(0) == '\"' && cellBuf.charAt(cellBuf.length() - 1) == '\"') { cellBuf.deleteCharAt(cellBuf.length() - 1); cellBuf.deleteCharAt(0); } // 两个双引号替换成一个 int twoQuotesIndex, // 双引号的位置 fromIndex = 0;// 查找双引号的起始位置 while ((twoQuotesIndex = cellBuf.indexOf("\"\"", fromIndex)) > -1) { // 两个双引号,删除一个 cellBuf.deleteCharAt(twoQuotesIndex); // 下次循环,从当前双引号的后面位置开始查找 fromIndex = twoQuotesIndex + 1; // 如果位置超出字符串,停止循环 if (fromIndex >= cellBuf.length()) { break; } } System.out.println(cellBuf); }
正则解题:
百度搜“CSV解析器”,答案很多。
相关文章推荐
- Java正影响着一代程序员
- 程序员笑话大全,程序员的这108个笑话,你都看得懂吗?
- 程序员求职面试三部曲之一:选择合适的工作单位(转)
- 关于sizeof的面试题,回答很好地解释了sizeof的相关特性
- 阿里面试
- 【面试题解答】如何在一个对象释放的时候收到通知
- 剑指offer之面试题23:从上往下打印二叉树
- 对程序员说的一些话
- 如何准备阿里社招面试,顺谈Java程序员学习中各阶段的建议
- web前端面试题:
- iTerm2-程序员必备神器(Mac)
- 大神博客地址列表
- About JAVA ,You Should Know-程序员的自我修养
- 程序员的书架上应该放的书
- 黑马程序员_java 基础
- Java面试题
- 面试题--多线程互斥(线程安全)
- 面试题--多线程
- Android面试题
- 那些著名或非著名的iOS面试题(中) 4000