module twoda; import std.string; import std.conv : to; import std.regex; class TwoDA{ import std.regex; import std.file; class ParseException : Exception{ this(in string s){super(s);} } this(string filepath){ lastLine = 0; foreach(index, line ; readText(filepath).splitLines){ string data[]; auto results = matchAll(line, rgxField); if(results.hit is null) throw new ParseException(filepath~":"~index.to!string~" Incorrect 2da line (not parseable)"); foreach(res ; results){ string s; if(res[0][0]=='"') data~= res[2]; else data~= res[1]; } if(index==0){ header = data; //writeln(header); } else{ int nLine = data[0].to!int; values[nLine] = data[1..$]; //writeln(values[nLine]); if(nLine > lastLine) lastLine = nLine; } } } string[] header; string[][uint] values; uint lastLine; enum rgxField = ctRegex!"(?:\\b([^\\s]+?)\\b|\"([^\"]+?)\")"; }