我有一個逗號分隔的文件,其中包含許多與下面類似的行。使用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