Skip to content

Instantly share code, notes, and snippets.

@paulsinnett
Last active September 17, 2017 17:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paulsinnett/cc65411ba82e1fb4035b356361e8ecbe to your computer and use it in GitHub Desktop.
Save paulsinnett/cc65411ba82e1fb4035b356361e8ecbe to your computer and use it in GitHub Desktop.
Useful CSV parsing code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CSV
{
static bool EvenQuotes(string entry)
{
bool even = true;
foreach (char letter in entry)
{
if (letter == '"')
{
even = !even;
}
}
return even;
}
static string TrimQuotes(string entry)
{
// trim any whitespace
entry = entry.Trim();
// if begins with a quote
if (entry.Length > 0 && entry[0] == '"')
{
// and ends with a quote
if (entry[entry.Length - 1] == '"')
{
// remove trailing quotes
entry = entry.Substring(1, entry.Length - 2);
// quoted quotes
if (entry.Contains("\"\""))
{
// de-double the quotes
entry = entry.Replace("\"\"", "\"");
}
}
else
{
// quote mismatch
Debug.LogWarningFormat("Quote mismatch in entry '{0}'", entry);
}
}
return entry;
}
static string ReplaceLineBreaks(string entry)
{
if (entry.Contains("\\n"))
{
// escape line breaks
entry = entry.Replace("\\n", "\n");
}
return entry;
}
public static List<string> SplitCSVLine(string line)
{
string[] commaSeparated = line.Split(new char [] { ',' });
List<string> entries = new List<string>();
string entry = string.Empty;
foreach (string segment in commaSeparated)
{
entry += segment;
if (EvenQuotes(entry))
{
entries.Add(ReplaceLineBreaks(TrimQuotes(entry)));
entry = string.Empty;
}
else
{
// re-add the trimmed comma
entry += ",";
}
}
if (entry != string.Empty)
{
Debug.LogWarningFormat("Found trailing text '{0}' while parsing CSV", entry);
}
return entries;
}
static string QuoteOutput(string entry)
{
// replace single quotes with double quotes
entry = entry.Replace("\"", "\"\"");
// de-escape line breaks
entry = entry.Replace("\n", "\\n");
if (entry.Contains(","))
{
// quote the entry
entry = string.Format("\"{0}\"", entry);
}
return entry;
}
public static string MakeCSVLine(string[] entries)
{
string line = string.Empty;
bool first = true;
foreach (string entry in entries)
{
if (!first)
{
line += ",";
}
line += QuoteOutput(entry);
first = false;
}
return line;
}
}
@paulsinnett
Copy link
Author

paulsinnett commented Sep 14, 2017

I wasted hours looking for a simple CSV read and write. In the end I wrote some code to handle the cases I needed to worry about:

  • quoted fields
  • commas inside quoted fields
  • newlines in fields (encoded as \n)

To turn an array of string into a CSV line call MakeCSVLine. To turn a CSV line into an array of strings call SplitCSVLine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment