WedX - журнал о программировании и компьютерных науках

Прочитайте csv, который имеет двойные кавычки с запятой внутри

ОБНОВЛЕНИЕ: РАБОЧЕЕ РЕШЕНИЕ РАЗМЕЩЕНО НИЖЕ

Я пытаюсь обработать файл 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;

    }
}

CSV-файл

Вывод (одна из строк с кавычками и запятой), хотя он и не идеален (запятая в кавычках съедена), это незначительная проблема, и мне лень ее исправлять, лол:

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 ```
21.03.2020

  • Используйте подходящую библиотеку CSV вместо firstline.split(","); — удачи! 21.03.2020
  • спасибо, я попробую это 21.03.2020
  • Игнорируйте запятые, когда вы находитесь внутри кавычек. Легко! Обрабатывать строку посимвольно.. 21.03.2020
  • @JGFMK Как мне это сделать? Это именно то, что мне нужно! Можете ли вы опубликовать какое-то решение для этого? Кроме того, в моем CSV-файле 100 000 строк. Будет ли это замедлять время выполнения, если я буду обрабатывать его посимвольно? 21.03.2020
  • Я бы так себе представлял. да, 21.03.2020
  • stackoverflow.com/a/23412989/495157 Об этом уже спрашивали.... 21.03.2020

Ответы:


1

Мое собственное решение: прочитайте первый символ каждого элемента, если первый символ является двойной кавычкой, объедините этот и следующие (для этого нужно будет использовать рекурсию), пока не будет элемент с двойной кавычкой в ​​качестве последнего символа.

Это будет работать значительно быстрее, чем чтение char за char, как это было предложено JGFMK. И мне не разрешено использовать внешние библиотеки для этого проекта.

ВСЕ ЕЩЕ РЕАЛИЗУЮ ЭТО, я обновлю, если это сработает

РЕДАКТИРОВАТЬ: рабочее решение опубликовано в исходном сообщении

24.03.2020

2

не изобретайте велосипед: есть библиотеки для чтения csv, например. https://commons.apache.org/proper/commons-csv/ https://opencsv.sourceforge.net/ https://code.google.com/archive/p/jcsv/

08.04.2020
  • Моя спецификация проекта не позволяет мне использовать внешние библиотеки 08.04.2020
  • Новые материалы

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

    ИИ в аэрокосмической отрасли
    Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


    Для любых предложений по сайту: [email protected]