C#写的一段解析 CSV 文件的代码 选择自 redv 的 Blog

我们经常将Excel格式的文件保存为csv格式以方便上传和修改,可是当数据中包含逗号和双引号的时候Excel会把该字段用双引号括住并把数据中的"改为""


下载: csv.cs
  1. using System;
  2.  /**//**
  3. * The Comma Separated Value (CSV) File Format:
  4.  http://www.creativyst.com/Doc/Articles/CSV/CSV01.htm
  5. * 描述:解析 CSV 格式的文件。
  6. * 由这里
  7.  http://blog.csdn.net/emu/archive/2003/03/01/16338.aspx 的Java代码改写而来(增加了行处理)
  8. * 日期: 2004-10-22 14:55
  9. */
  10.  namespace Mitumori {
  11.  /**//// <summary>
  12.  /// CSVUtil 用来处理CSV格式的文件内容成一二维数组。
  13.  /// </summary>
  14.  public class CSVUtil {
  15.  private CSVUtil() {
  16.  }
  17.  
  18.  /**//// <summary>
  19.  /// 分割 CVS 文件内容为一个二维数组。
  20.  /// </summary>
  21.  /// <param name="src">CVS 文件内容字符串</param>
  22.  /// <returns>二维数组。String[line count][column count]</returns>
  23.  public static String[][] SplitCSV(String src) {
  24.  // 如果输入为空,返回 0 长度字符串数组
  25.  if (src==null || src.Length == 0) return new String[0][]{};
  26.  String st="";
  27.  System.Collections.ArrayList lines = new System.Collections.ArrayList(); // 行集合。其元素为行
  28.  System.Collections.ArrayList cells = new System.Collections.ArrayList(); // 单元格集合。其元素为一个单元格
  29.  bool beginWithQuote = false;
  30.  int maxColumns = 0;
  31.  // 遍历字符串的字符
  32.  for (int i=0;i<src.Length;i++){
  33.  char ch = src[i];
  34.  
  35.  CR 或者 LF#region CR 或者 LF
  36.  //A record separator may consist of a line feed (ASCII/LF=0x0A),
  37.  //or a carriage return and line feed pair (ASCII/CRLF=0x0D 0x0A).
  38.  // 这里我不明白CR为什么不作为separator呢,在Mac OS上好像是用CR的吧。
  39.  // 这里我&ldquo;容错&rdquo;一下,CRLF、LFCR、CR、LF都作为separator
  40.  if (ch == ' ') {
  41.  CR#region CR
  42.  if (beginWithQuote) {
  43.  st += ch;
  44.  }
  45.  else {
  46.  if(i+1 < src.Length && src[i+1] == ' ') { // 如果紧接的是LF,那么直接把LF吃掉
  47.  i++;
  48.  }
  49.  
  50.  //line = new String[cells.Count];
  51.  //System.Array.Copy (cells.ToArray(typeof(String)), line, line.Length);
  52.  //lines.Add(line); // 把上一行放到行集合中去
  53.  
  54.  cells.Add(st);
  55.  st = "";
  56.  beginWithQuote = false;
  57.  
  58.  maxColumns = (cells.Count > maxColumns ? cells.Count : maxColumns);
  59.  lines.Add(cells);
  60.  st = "";
  61.  cells = new System.Collections.ArrayList();
  62.  }
  63. #endregion CR
  64.  }
  65.  else if (ch == ' ') {
  66.  LF#region LF
  67.  if (beginWithQuote) {
  68.  st += ch;
  69.  }
  70.  else {
  71.  if(i+1 < src.Length && src[i+1] == ' ') { // 如果紧接的是LF,那么直接把LF吃掉
  72.  i++;
  73.  }
  74.  
  75.  //line = new String[cells.Count];
  76.  //System.Array.Copy (cells.ToArray(typeof(String)), line, line.Length);
  77.  //lines.Add(line); // 把上一行放到行集合中去
  78.  
  79.  cells.Add(st);
  80.  st = "";
  81.  beginWithQuote = false;
  82.  
  83.  maxColumns = (cells.Count > maxColumns ? cells.Count : maxColumns);
  84.  lines.Add(cells);
  85.  st = "";
  86.  cells = new System.Collections.ArrayList();
  87.  }
  88. #endregion LF
  89.  }
  90. #endregion CR 或者 LF
  91.  else if (ch == '"'){ // 双引号
  92. 双引号#region 双引号
  93.  if (beginWithQuote){
  94.  i++;
  95.  if (i>=src.Length){
  96.  cells.Add(st);
  97.  st="";
  98.  beginWithQuote=false;
  99.  }
  100.  else{
  101.  ch=src[i];
  102.  if (ch == '"'){
  103.  st += ch;
  104.  }
  105.  else if (ch == ','){
  106.  cells.Add(st);
  107.  st="";
  108.  beginWithQuote = false;
  109.  }
  110.  else{
  111.  throw new Exception("Single double-quote char mustn't exist in filed "
  112. +(cells.Count+1)+" while it is begined with quote char at:"+i);
  113.  }
  114.  }
  115.  }
  116.  else if (st.Length==0){
  117.  beginWithQuote = true;
  118.  }
  119.  else{
  120.  throw new Exception("Quote cannot exist in a filed which doesn't begin with quote! field:"+(cells.Count+1));
  121.  }
  122. #endregion 双引号
  123.  }
  124.  else if (ch==','){
  125. 逗号#region 逗号
  126.  if (beginWithQuote){
  127.  st += ch;
  128.  }
  129.  else{
  130.  cells.Add(st);
  131.  st = "";
  132.  beginWithQuote = false;
  133.  }
  134. #endregion 逗号
  135.  }
  136.  else{
  137. 其它字符#region 其它字符
  138.  st += ch;
  139. #endregion 其它字符
  140.  }
  141.  
  142.  }
  143.  if (st.Length != 0){
  144.  if (beginWithQuote){
  145.  throw new Exception("last field is begin with but not end with double quote");
  146.  }
  147.  else{
  148.  cells.Add(st);
  149.  maxColumns = (cells.Count > maxColumns ? cells.Count : maxColumns);
  150.  lines.Add(cells);
  151.  }
  152.  }
  153.  
  154.  String[][] ret = new String[lines.Count][];
  155.  for (int i = 0; i < ret.Length; i++) {
  156.  cells = (System.Collections.ArrayList) lines[i];
  157.  ret[i] = new String[maxColumns];
  158.  for (int j = 0; j < maxColumns; j++) {
  159.  ret[i][j] = cells[j].ToString();
  160.  }
  161.  }
  162.  //System.Array.Copy(lines.ToArray(typeof(String[])), ret, ret.Length);
  163.  return ret;
  164.  }
  165.  
  166.  public static void aMain(String[] args){
  167.  String src1= ""fh,zg",sdf,"asfs,",",dsdf","
  168. +""aadf""","""hdfg","fgh""dgnh","
  169. +"hgfg'dfh,"asdfa""""","""""fgjhg","
  170. +""gfhg""""hb" ";
  171.  try {
  172.  String[][] Ret = SplitCSV(src1);
  173.  for (int i=0;i<Ret.Length;i++){
  174.  for (int j = 0; j < Ret[i].Length; i++) {
  175.  System.Console.WriteLine(Ret[i][j]);
  176.  }
  177.  System.Console.WriteLine();
  178.  }
  179.  }
  180.  catch(Exception e) {
  181.  System.Console.WriteLine(e.StackTrace);
  182.  }
  183.  }
  184.  }
  185.  }
引用通告地址: 点击获取引用地址
评论: 0 | 引用: 0 | 阅读: 2260
发表评论
昵 称: 密 码:
网 址: 邮 箱:
选 项:    
头 像:
内 容: