您的位置:首页 > 职场人生

CSV解析器,CSV解释器,新媒传信上机题,新媒传信面试,java解析csv

2016-04-26 15:19 603 查看
原题:



更复杂点的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解析器”,答案很多。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: