更新:以下发布的解决方案
我正在尝试处理一个csv文件,并用逗号对其进行分割。但是,有几个带有引号的地方都嵌入了逗号。
示例:“#29.正确识别,存储和使用有毒物质”
每个带有逗号的引号都用“”引起来,是否有办法检测到双引号并解决逗号?
谢谢!
原始代码:
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.FileWriter;
import java.io.PrintWriter;
public class csvFileReader {
public static void main(String[] args) {
String csvFile = "/Users/zzmle/Desktop/data.csv";
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
int count=0;
try {
br = new BufferedReader(new FileReader(csvFile));
String firstline = br.readLine();
String[] header = firstline.split(",");
while ((line = br.readLine()) != null && count<10) {
//comma is the separator
String[] Restaurant = line.split(cvsSplitBy);
for (int i=0; i<header.length; i++) {
System.out.println(header[i]+": "+Restaurant[i]+" ");
}
System.out.println("-------------------");
count++;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
工作解决方案:
// @author Zhiming Zhao
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.FileWriter;
import java.io.PrintWriter;
public class csvFileReader {
public static void main(String[] args) {
String csvFile = "data.csv";
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
int count=0;
try {
br = new BufferedReader(new FileReader(csvFile));
String firstline = br.readLine();
String[] header = firstline.split(cvsSplitBy);
while ((line = br.readLine()) != null && count<10) { //count<10 is for testing purposes
String[] Restaurant = line.split(cvsSplitBy); //comma is the separator
process(Restaurant); //this is to deal with the commas within quotation marks (which split the elements and shifts them into the wrong places)
//this part prints the header + restaurant for the first ten lines
for (int i=0; i<header.length; i++) {
System.out.println(header[i]+": "+Restaurant[i]+" ");
}
System.out.println("-------------------");
count++;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("The file cannot be found, check if the file is under root directory");
} catch (IOException e) {
e.printStackTrace();
System.out.println("Input & Output operations error");
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// @brief This function specifically deal with the issue of commas within the quotation marks
// @detail it gets the index number of the 2 elements containing the quotation marks, then concats them all. It works with multiple quotation marks on the same line
public static void process(String[] data) {
int index1 = -1; //initialize the index of the first ", -1 for empty
int index2 = 0; //initialize the index of the second ", 0 for empty
for (int i=0; i<data.length; i++) {
if (String.valueOf(data[i].charAt(0)).equals("\"") && index1 == -1) { //if index1 is not empty and the first char of current element is "
index1 = i; //set index1 to current index number
}
if (String.valueOf(data[i].charAt(data[i].length()-1)).equals("\"") && index1 != -1) { //if index1 is not empty and the last char of current element is "
index2 = i; //set index2 to current index number
multiconcat(index1, index2, data); //concat the elements between index1 and index2
data = multidelet(index1+1, index2, data); //delete the elements that were copied (index1+1:index2)
i -= (index2-index1); //this is to reset the cursor back to index1 (could be replaced with i = index1)
index1 = -1; //set index1 to empty
}
}
}
// @brief Copy all elements between index1 and index2 to index1, doesn't return anything
public static void multiconcat(int index1, int index2, String[] data) {
for (int i=index1+1; i<=index2; i++) {
data[index1] += data[i];
}
}
// @brief Deletes the elements between index1+1 and index2
public static String[] multidelet(int index1, int index2, String[] data) {
String[] newarr = new String[data.length-(index2-index1+1)];
int n = 0;
for (int i=0; i<data.length; i++) {
if (index1 <= i && i <= index2) continue;
newarr[n] = data[i];
n++;
}
return newarr;
}
}
输出(带引号和逗号的行之一),虽然不是很完美(被引号引起的逗号被吃掉了),但这是一个小问题,我懒得修复它:
serial_number: DA08R0TCU
activity_date: 03/30/2018 12:00:00 AM
facility_name: KRUANG TEDD
violation_code: F035
violation_description: "# 35. Equipment/Utensils - approved; installed; clean; good repair capacity"
violation_status: capacity"
points: OUT OF COMPLIANCE
grade: 1
facility_address: A
facility_city: 5151 HOLLYWOOD BLVD
facility_id: LOS ANGELES
facility_state: FA0064949
facility_zip: CA
employee_id: 90027
owner_id: EE0000857
owner_name: OW0001034
pe_description: 5151 HOLLYWOOD LLC
program_element_pe: RESTAURANT (31-60) SEATS HIGH RISK
program_name: 1635
program_status: KRUANG TEDD
record_id: ACTIVE
score: PR0031205
service_code: 92
service_description: 1
row_id: ROUTINE INSPECTION ```
答案 0 :(得分:0)
我自己的解决方案: 读取每个元素的第一个字符,如果第一个字符是双引号,则将其与后一个(并需要使用递归)进行合并,直到有一个元素将双引号作为最后一个字符。
这比JGFMK建议的逐字符读取要快得多。 而且不允许我为此项目使用外部库。
仍然可以执行此操作,如果可以的话我会进行更新
编辑:工作解决方案发布在原始帖子中
答案 1 :(得分:0)