Подтвердить что ты не робот

Разделение csv файла с кавычками как разделитель текста с помощью String.split()

У меня есть файл с разделителями-запятыми со многими строками, похожими на один ниже.

Sachin,,M,"Maths,Science,English",Need to improve in these subjects.

Цитаты используются для выхода из разделительной запятой, используемой для представления нескольких значений.

Теперь, как разделить указанное значение в разделителе запятой с помощью String.split(), если это вообще возможно?

4b9b3361

Ответ 1

public static void main(String[] args) {
    String s = "Sachin,,M,\"Maths,Science,English\",Need to improve in these subjects.";
    String[] splitted = s.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)");
    System.out.println(Arrays.toString(splitted));
}

Вывод:

[Sachin, , M, "Maths,Science,English", Need to improve in these subjects.]

Ответ 2

Поскольку ваши проблемы/требования не все настолько сложны, можно использовать собственный метод, который выполняет более 20 раз быстрее и дает те же результаты. Это переменная, основанная на размере данных и количестве проанализированных строк, а для более сложных проблем с использованием регулярных выражений обязательно.

import java.util.Arrays;
import java.util.ArrayList;
public class SplitTest {

public static void main(String[] args) {

    String s = "Sachin,,M,\"Maths,Science,English\",Need to improve in these subjects.";
    String[] splitted = null;

 //Measure Regular Expression
    long startTime = System.nanoTime();
    for(int i=0; i<10; i++)
    splitted = s.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)");
    long endTime =   System.nanoTime();

    System.out.println("Took: " + (endTime-startTime));
    System.out.println(Arrays.toString(splitted));
    System.out.println("");


    ArrayList<String> sw = null;        
 //Measure Custom Method
            startTime = System.nanoTime();
    for(int i=0; i<10; i++)
    sw = customSplitSpecific(s);
    endTime =   System.nanoTime();

    System.out.println("Took: " + (endTime-startTime));
    System.out.println(sw);         
}

public static ArrayList<String> customSplitSpecific(String s)
{
    ArrayList<String> words = new ArrayList<String>();
    boolean notInsideComma = true;
    int start =0, end=0;
    for(int i=0; i<s.length()-1; i++)
    {
        if(s.charAt(i)==',' && notInsideComma)
        {
            words.add(s.substring(start,i));
            start = i+1;                
        }   
        else if(s.charAt(i)=='"')
        notInsideComma=!notInsideComma;
    }
    words.add(s.substring(start));
    return words;
}   

}

На моем собственном компьютере это производит:

Took: 6651100
[Sachin, , M, "Maths,Science,English", Need to improve in these subjects.]

Took: 224179
[Sachin, , M, "Maths,Science,English", Need to improve in these subjects.]

Ответ 3

Если ваши строки хорошо сформированы, это возможно со следующим регулярным выражением:

String[] res = str.split(",(?=([^\"]|\"[^\"]*\")*$)");

Выражение гарантирует, что разделение происходит только в запятых, за которыми следует четное (или ноль) количество кавычек (и, следовательно, не внутри таких кавычек).

Тем не менее, может быть проще использовать простой парсер без регулярных выражений.