Dividindo um arquivo csv com aspas como delimitador de texto usando String.split ()

Eu tenho um arquivo separado por vírgulas com muitas linhas semelhantes a uma abaixo.

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

Quotes é usado para escaping da vírgula delimitadora usada para representar vários valores.

Agora, como dividir o valor acima no delimitador de vírgula usando String.split() se for possível?

 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)); } 

Saída:

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

Como os seus problemas / requisitos não são tão complexos, um método personalizado pode ser utilizado com desempenho 20 vezes mais rápido e produz os mesmos resultados. Isso é variável com base no tamanho dos dados e no número de linhas analisadas, e para problemas mais complicados usando expressões regulares é uma obrigação.

 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 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 customSplitSpecific(String s) { ArrayList words = new ArrayList(); boolean notInsideComma = true; int start =0, end=0; for(int i=0; i 

}

No meu próprio computador, isso produz:

 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.] 

Se suas strings forem todas bem formadas, é possível com a seguinte expressão regular:

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

A expressão garante que uma divisão ocorra apenas com vírgulas, as quais são seguidas por um número par (ou zero) de aspas (e, portanto, não dentro dessas aspas).

No entanto, pode ser mais fácil usar um analisador simples que não seja regex.

Intereting Posts