Last active
September 17, 2017 17:43
-
-
Save paulsinnett/cc65411ba82e1fb4035b356361e8ecbe to your computer and use it in GitHub Desktop.
Useful CSV parsing code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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:
To turn an array of string into a CSV line call
MakeCSVLine
. To turn a CSV line into an array of strings callSplitCSVLine
.