1. 程式人生 > >C#獲取CSV檔案內容對逗號和引號分隔的處理

C#獲取CSV檔案內容對逗號和引號分隔的處理

在小批量資料匯入的時候,最常用的就是使用excel工具,將資料儲存為xls或csv檔案,然後上傳到伺服器,然後讀取出來通過資料庫訪問類的相關方法更新到資料庫中。對於如何讀取xls檔案的方法,網上太多了,使用excel物件或ole db/odbc連線都行。對於csv檔案,其中有一種方式就是通過檔案流,將它作為文字讀取出來,這其中會遇到一點小意外。

    我們知道,使用excel工具儲存成csv檔案時有幾個規則:

1、每一行的單元格內容之間用逗號分隔。

2、如果單元格的內容本身有逗號,這個單元格的內容將會用引號包含。

3、如果單元格的內容本身有引號,

    引號不在首或尾,這個單元格內容不會被引號包含。

    引號在首或尾,這個單元格內容會被引號包含且原來首尾的引號會被轉義。

    所以對於這樣的內容,直接按逗號或引號使用split方法明顯不合適,需要預先處理一下。辦法很多,最容易想到的就是用正則過濾掉本身帶逗號或引號的內容,剩下的再按逗號split就方便了,我將csv檔案中的每一行獲取出來存放到一個鍵值對的集合中,為了保證前後順序一致,使用SortedList,這裡用控制檯程式示例一下:

 1string s =string.Empty;
 2string src =string.Empty;
 3SortedList sl =new SortedList();
 4StreamReader fs 
=new StreamReader(new FileStream("demo.csv", FileMode.Open, FileAccess.Read), Encoding.GetEncoding("gb2312"));
 5while (!string.IsNullOrEmpty(s = fs.ReadLine()))
 6{
 7if (!string.IsNullOrEmpty(s))
 8    {
 9        Console.WriteLine(s);
10        src = s.Replace("\"\"""'");
11        MatchCollection col 
= Regex.Matches(src, ",\"([^\"]+)\",", RegexOptions.ExplicitCapture);12        IEnumerator ie = col.GetEnumerator();
13while (ie.MoveNext())
14        {
15string patn = ie.Current.ToString();
16int key = src.Substring(0, src.IndexOf(patn)).Split(',').Length;
17if (!sl.ContainsKey(key))
18            {
19                sl.Add(key, patn.Trim(newchar[] { ',''"' }).Replace("'""\""));20                src = src.Replace(patn, ",,");
21            }
22        }
2324string[] arr = src.Split(',');
25for (int i =0; i < arr.Length; i++)
26        {
27if (!sl.ContainsKey(i))
28                sl.Add(i, arr[i]);
29        }
3031        IDictionaryEnumerator ienum = sl.GetEnumerator();
32while (ienum.MoveNext())
33        {
34            Console.WriteLine(string.Format("{0}:{1}", ienum.Key, ienum.Value.ToString().Replace("'""\"")));35        }
36        sl.Clear();
37        src =string.Empty;
38    }
39    Console.Read();
40}
41fs.Close();