我有一个逗号分隔的文件,其中包含许多与下面类似的行。使用String.split()将文本分隔符分割为csv文件
Sachin,,M,"Maths,Science,English",Need to improve in these subjects.
引号用于转义用于表示多个值的分隔符逗号。
现在如何尽可能地使用String.split()
将逗号分隔符上的上述值分开?
我有一个逗号分隔的文件,其中包含许多与下面类似的行。使用String.split()将文本分隔符分割为csv文件
Sachin,,M,"Maths,Science,English",Need to improve in these subjects.
引号用于转义用于表示多个值的分隔符逗号。
现在如何尽可能地使用String.split()
将逗号分隔符上的上述值分开?
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.]
+1这是一个非常很酷的正则表达式。我以前没有见过这个,但它的工作原理!我觉得这是非常好的我会奖励你一个赏金:)(注意:赏金过程需要很多天才能完成) – Bohemian
我花了一段时间才弄清楚这个正则表达式在做什么。它会帮助我极大地解释它匹配的逗号后跟偶数个引号(或没有引号)。所以这是有效的,因为逗号的内部引号(即我们不想匹配/分割的引号)应该在它们和行尾之间有奇数的引号。也可能值得注意的是,如果数据可能已经逃脱了引号,我认为这将不起作用。 – glyphx
做这个s.split(',(?=([^ \“] * \”[^ \“] * \”)* [^ \“] * $)',-1)如果你想保留空字符串在结尾。http://stackoverflow.com/questions/13939675/java-string-split-i-want-it-to-include-the-empty-strings-at-the-end – kctang
如果字符串所有合式有可能用以下正则表达式:
String[] res = str.split(",(?=([^\"]|\"[^\"]*\")*$)");
表达确保分裂仅在其后面的偶数(或零)数逗号发生引号(因此不在此类引号内)。
尽管如此,使用简单的非正则表达式解析器可能更容易。
阅读CSV文件它工作正常。如果你有这种类型的格式987663,seepzBranch,“Seepz孟买,andheri”,“近红外线,平23号,raghilla商场thane”,seepz, –
作为您的问题/要求不那么复杂的自定义方法可以利用,超过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.]
-1这并不回答这个问题,它特别要求使用'String.split()'的解决方案。顺便说一句,由对java知之甚少的人编写的代码的特征之一是使用'Vector'。 – Bohemian
请解释为什么在这种情况下使用ArrayList而不是Vector(除了由于线程安全性而导致的性能下降)将更加有利。此外,你的礼貌可以使用一些工作,这是一个粗鲁的人的标志之一。 –
我不是粗鲁的;仅仅是事实。这里有一点小技巧......'Vector'不是线程安全的。这是一个破碎的课程,这就是为什么没有人,我真的意味着*没有人*在现实世界中使用它。只有总的初学者使用它,我的猜测是因为讲义十年过时了,特别是因为主张使用Vector的讲师在学术界花费了太多的时间来保持联系,并且老的谚语“如果你不能做它,教它“仍然是真实的。 – Bohemian
为什么你坚持使用String.split?这个例子有更好的选择吗? – user949300