Skip to main content
Revised code sample
Source Link
        static List<List<string>> ParseCsv(string csv) {
            var parsedCsv = new List<List<string>>();
            var row = new List<string>();
            string field = "";
            bool escapedinQuotedField = false;

            for (int i = 0; i < csv.Length; i++) {
                char current = csv[i];
                char next = i == csv.Length - 1 ? ' ' : csv[i + 1];

                if (current != '"' && current != ',' && current != '\r'// &&if current !=character '\n')is {
not a quote or comma or carriage return or newline (or not a quote and currently in an a quoted field += current;
           ), just add the character to the current field continue;text
                }

if ((current != '"' && current != ',' && current != '\r' && current != '\n') if|| (current ==!= '"' && inQuotedField)) {
                    if (escaped && next ==field '"')+= {current;
                } else if (current == ' ' || i++;current //skip== escaping'\t') quote{
                        field += current;continue; //add escaped quoteignore character
whitespace outside a quoted field
                } else if (escapedcurrent == '"') {
                       if row.Add(field);
         inQuotedField && next == '"') { // quote is escaping a quote within a quoted field = "";
                        escaped = false;
     i++; // skip escaping quote
           } else {
           field += current;
           escaped = true;
       } else if (inQuotedField) { // quote signifies the end of a quoted }field
                    continue;
        row.Add(field);
        }

                if (currentnext == ',') {
                    if (escaped) {
          i++; // skip the comma separator since we've already found the end of the field += current;
                    } else {
                        row.Add(field);}
                        field = "";
                    }
                    continue;
                }

                if (current ==inQuotedField '\r')= {false;
                    if} (escaped)else {
                // quote signifies the beginning of a quoted field += current;
                    } else {
                     inQuotedField = true; continue;
                    }
                }

               else if (current == '\n'',') {
  //
                   if row.Add(escapedfield) {;
                        field +== current;"";
                    } else {
if (current == '\n') {
                    row.Add(field);
                        parsedCsv.Add(new List<string>(row));
                        field = "";
                        row.Clear();
                    }
                    continue;
                }
            }

            return parsedCsv;
        }

  static List<List<string>> ParseCsv(string csv) {
            var parsedCsv = new List<List<string>>();
            var row = new List<string>();
            string field = "";
            bool escaped = false;

            for (int i = 0; i < csv.Length; i++) {
                char current = csv[i];
                char next = i == csv.Length - 1 ? ' ' : csv[i + 1];

                if (current != '"' && current != ',' && current != '\r' && current != '\n') {
                    field += current;
                    continue;
                }

                if (current == '"') {
                    if (escaped && next == '"') {
                        i++; //skip escaping quote
                        field += current; //add escaped quote character
                    } else if (escaped) {
                        row.Add(field);
                        field = "";
                        escaped = false;
                    } else {
                        escaped = true;
                    }
                    continue;
                }

                if (current == ',') {
                    if (escaped) {
                        field += current;
                    } else {
                        row.Add(field);
                        field = "";
                    }
                    continue;
                }

                if (current == '\r') {
                    if (escaped) {
                        field += current;
                    } else {
                        continue;
                    }
                }

                if (current == '\n') {
                     if (escaped) {
                        field += current;
                    } else {
                        row.Add(field);
                        parsedCsv.Add(new List<string>(row));
                        field = "";
                        row.Clear();
                    }
                    continue;
                }
            }

            return parsedCsv;
        }

        static List<List<string>> ParseCsv(string csv) {
            var parsedCsv = new List<List<string>>();
            var row = new List<string>();
            string field = "";
            bool inQuotedField = false;

            for (int i = 0; i < csv.Length; i++) {
                char current = csv[i];
                char next = i == csv.Length - 1 ? ' ' : csv[i + 1];

                // if current character is not a quote or comma or carriage return or newline (or not a quote and currently in an a quoted field), just add the character to the current field text
                if ((current != '"' && current != ',' && current != '\r' && current != '\n') || (current != '"' && inQuotedField)) {
                    field += current;
                } else if (current == ' ' || current == '\t') {
                    continue; // ignore whitespace outside a quoted field
                } else if (current == '"') {
                    if (inQuotedField && next == '"') { // quote is escaping a quote within a quoted field
                        i++; // skip escaping quote
                        field += current;
                    } else if (inQuotedField) { // quote signifies the end of a quoted field
                        row.Add(field);
                        if (next == ',') {
                            i++; // skip the comma separator since we've already found the end of the field
                        }
                        field = "";
                        inQuotedField = false;
                    } else { // quote signifies the beginning of a quoted field
                        inQuotedField = true; 
                    }
                } else if (current == ',') { //
                    row.Add(field);
                    field = "";
                } else if (current == '\n') {
                    row.Add(field);
                    parsedCsv.Add(new List<string>(row));
                    field = "";
                    row.Clear();
                }
            }

            return parsedCsv;
        }

Source Link

Here's a solution I coded up today for a situation where I needed to parse a CSV without relying on external libraries. I haven't tested performance for large files since it wasn't relevant to my particular use case but I'd expect it to perform reasonably well for most situations.

  static List<List<string>> ParseCsv(string csv) {
            var parsedCsv = new List<List<string>>();
            var row = new List<string>();
            string field = "";
            bool escaped = false;

            for (int i = 0; i < csv.Length; i++) {
                char current = csv[i];
                char next = i == csv.Length - 1 ? ' ' : csv[i + 1];

                if (current != '"' && current != ',' && current != '\r' && current != '\n') {
                    field += current;
                    continue;
                }

                if (current == '"') {
                    if (escaped && next == '"') {
                        i++; //skip escaping quote
                        field += current; //add escaped quote character
                    } else if (escaped) {
                        row.Add(field);
                        field = "";
                        escaped = false;
                    } else {
                        escaped = true;
                    }
                    continue;
                }

                if (current == ',') {
                    if (escaped) {
                        field += current;
                    } else {
                        row.Add(field);
                        field = "";
                    }
                    continue;
                }

                if (current == '\r') {
                    if (escaped) {
                        field += current;
                    } else {
                        continue;
                    }
                }

                if (current == '\n') {
                    if (escaped) {
                        field += current;
                    } else {
                        row.Add(field);
                        parsedCsv.Add(new List<string>(row));
                        field = "";
                        row.Clear();
                    }
                    continue;
                }
            }

            return parsedCsv;
        }