Implements functionality to read Comma Separated Values and its variants from a input range of dchar.
Comma Separated Values provide a simple means to transfer and store
tabular data. It has been common for programs to use their own
variant of the CSV format. This parser will loosely follow the
RFC-4180. CSV input should adhered
to the following criteria, differences from RFC-4180 in parentheses.
import std.algorithm; import std.array; import std.csv; import std.stdio; import std.typecons; void main() { auto text = "Joe,Carpenter,300000\nFred,Blacksmith,400000\r\n"; foreach(record; csvReader!(Tuple!(string,string,int))(text)) { writefln("%s works as a %s and earns $%d per year", record[0], record[1], record[2]); } }
auto text = "Name,Occupation,Salary\r" "Joe,Carpenter,300000\nFred,Blacksmith,400000\r\n"; foreach(record; csvReader!(string[string]) (text, null)) { writefln("%s works as a %s and earns $%s per year.", record["Name"], record["Occupation"], record["Salary"]); }
Exception containing the row and column for when an exception was thrown.
Numbering of both row and col start at one and corresponds to the location
in the file rather than any specified header. Special consideration should
be made when there is failure to match the header see HeaderMismatchException
for details.
When performing type conversions, std.ConvException.ConvException is stored in the next field.
Exception thrown when a Token is identified to not be completed: a quote is found in an unquoted field, data continues after a closing quote, or the quoted field was not closed before data was empty.
Data pulled from input before finding a problem
This field is populated when using csvReader but not by csvNextToken as this data will have already been fed to the output range.
Exception thrown under different conditions based on the type of Contents.
Structure, Class, and Associative Array
Determines the behavior for when an error is detected.
Disabling exception will follow these rules:
No exceptions are thrown due to incorrect CSV.
Use exceptions when input has incorrect CSV.
Returns an input range for iterating over records found in input.
The Contents of the input can be provided if all the records are the
same type such as all integer data:
string str = `76,26,22`; int[] ans = [76,26,22]; auto records = csvReader!int(str); foreach(record; records) { assert(equal(record, ans)); }
string str = "Hello;65;63.63\nWorld;123;3673.562"; struct Layout { string name; int value; double other; } auto records = csvReader!Layout(str,';'); foreach(record; records) { writeln(record.name); writeln(record.value); writeln(record.other); }
string str = "A \" is now part of the data"; auto records = csvReader!(string,Malformed.ignore)(str); auto record = records.front; assert(record.front == str);
An optional header can be provided. The first record will be read in as the header. If Contents is a struct then the header provided is expected to correspond to the fields in the struct. When Contents is not a type which can contain the entire record, the header must be provided in the same order as the input or an exception is thrown.
Read only column "b":
string str = "a,b,c\nHello,65,63.63\nWorld,123,3673.562"; auto records = csvReader!int(str, ["b"]); auto ans = [[65],[123]]; foreach(record; records) { assert(equal(record, ans.front)); ans.popFront(); }
string str = "a,b,c\nHello,65,63.63\nWorld,123,3673.562"; struct Layout { int value; double other; string name; } auto records = csvReader!Layout(str, ["b","c","a"]);
string str = "a,b,c\nHello,65,63.63\nWorld,123,3673.562"; auto records = csvReader(str, null); assert(records.header == ["a","b","c"]);
string str = "a,b,c\nHello,65,63.63"; auto records = csvReader(str, ["a"]); assert(records.header == ["a","b","c"]);
Lower level control over parsing CSV
This function consumes the input. After each call the input will
start with either a delimiter or record break (\n, \r\n, \r) which
must be removed for subsequent calls.
string str = "65,63\n123,3673"; auto a = appender!(char[])(); csvNextToken(str,a,',','"'); assert(a.data == "65"); assert(str == ",63\n123,3673"); str.popFront(); a.shrinkTo(0); csvNextToken(str,a,',','"'); assert(a.data == "63"); assert(str == "\n123,3673"); str.popFront(); a.shrinkTo(0); csvNextToken(str,a,',','"'); assert(a.data == "123"); assert(str == ",3673");
Range input | Any CSV input |
Output ans | The first field in the input |
Separator sep | The character to represent a comma in the specification |
Separator quote | The character to represent a quote in the specification |
bool startQuoted | Whether the input should be considered to already be in quotes |