Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page.
Requires a signed-in GitHub account. This works well for small changes.
If you'd like to make larger changes you may want to consider using
a local clone.
std.csv
Implements functionality to read Comma Separated Values and its variants
from an 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 adhere
to the following criteria (differences from RFC-4180 in parentheses):
- A record is separated by a new line (CRLF,LF,CR)
- A final record may end with a new line
- A header may be provided as the first record in input
- A record has fields separated by a comma (customizable)
- A field containing new lines, commas, or double quotes should be enclosed in double quotes (customizable)
- Double quotes in a field are escaped with a double quote
- Each record should contain the same number of fields
Example
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]); } // To read the same string from the file "filename.csv": auto file = File("filename.csv", "r"); foreach (record; file.byLine.joiner("\n").csvReader!(Tuple!(string, string, int))) { writefln("%s works as a %s and earns $%d per year", record[0], record[1], record[2]); } } }When an input contains a header the Contents can be specified as an associative array. Passing
null
to signify that a header is present.
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"]); }This module allows content to be iterated by record stored in a struct, class, associative array, or as a range of fields. Upon detection of an error an CSVException is thrown (can be disabled). csvNextToken has been made public to allow for attempted recovery. Disabling exceptions will lift many restrictions specified above. A quote can appear in a field if the field was not quoted. If in a quoted field any quote by itself, not at the end of a field, will end processing for that field. The field is ended when there is no input, even if the quote was not closed.
See Also:
License:
Authors:
Jesse Phillips
Source std/csv.d
- class
CSVException
: object.Exception; - 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.conv.ConvException is stored in the next field.
- size_t
row
; - size_t
col
;
- class
IncompleteCellException
: std.csv.CSVException; - 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.
- dstring
partialData
; - Data pulled from input before finding a problemThis field is populated when using csvReader but not by csvNextToken as this data will have already been fed to the output range.
- class
HeaderMismatchException
: std.csv.CSVException; - Exception thrown under different conditions based on the type of Contents.Structure, Class, and Associative Array
- When a header is provided but a matching column is not found
- When a header is provided but a matching column is not found
- Order did not match that found in the input
- enum
Malformed
: int; - Determines the behavior for when an error is detected.Disabling exception will follow these rules:
- A quote can appear in a field if the field was not quoted.
- If in a quoted field any quote by itself, not at the end of a field, will end processing for that field.
- The field is ended when there is no input, even if the quote was not closed.
- If the given header does not match the order in the input, the content will return as it is found in the input.
- If the given header contains columns not found in the input they will be ignored.
ignore
- No exceptions are thrown due to incorrect CSV.
throwException
- Use exceptions when input has incorrect CSV.
- auto
csvReader
(Contents = string, Malformed ErrorLevel = Malformed.throwException, Range, Separator = char)(Rangeinput
, Separatordelimiter
= ',', Separatorquote
= '"')
if (isInputRange!Range && is(Unqual!(ElementType!Range) == dchar) && isSomeChar!Separator && !is(Contents T : T[U], U : string)); - Returns an
input
range for iterating over records found ininput
.The Contents of theinput
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)); }
Example using a struct with modifieddelimiter
: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); }
Specifying ErrorLevel as Malformed.ignore will lift restrictions on the format. This example shows that an exception is not thrown when finding aquote
in a field not quoted.string str = "A \" is now part of the data"; auto records = csvReader!(string,Malformed.ignore)(str); auto record = records.front; assert(record.front == str);
Returns:Aninput
range R as defined by std.range.primitives.isInputRange. When Contents is a struct, class, or an associative array, the element type of R is Contents, otherwise the element type of R is itself a range with element type Contents.Throws:CSVException When aquote
is found in an unquoted field, data continues after a closingquote
, the quoted field was not closed before data was empty, a conversion failed, or when the row's length does not match the previous length. HeaderMismatchException when a header is provided but a matching column is not found or the order did not match that found in theinput
. Read the exception documentation for specific details of when the exception is thrown for different types of Contents. - auto
csvReader
(Contents = string, Malformed ErrorLevel = Malformed.throwException, Range, Header, Separator = char)(Rangeinput
, Headerheader
, Separatordelimiter
= ',', Separatorquote
= '"')
if (isInputRange!Range && is(Unqual!(ElementType!Range) == dchar) && isSomeChar!Separator && isForwardRange!Header && isSomeString!(ElementType!Header)); - An optional
header
can be provided. The first record will be read in as theheader
. If Contents is a struct then theheader
provided is expected to correspond to the fields in the struct. When Contents is not a type which can contain the entire record, theheader
must be provided in the same order as theinput
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(); }
Read fromheader
of different order: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"]);
Theheader
can also be left empty if theinput
contains aheader
but all columns should be iterated. Theheader
from theinput
can always be accessed from theheader
field.string str = "a,b,c\nHello,65,63.63\nWorld,123,3673.562"; auto records = csvReader(str, null); assert(records.header == ["a","b","c"]);
Returns:Aninput
range R as defined by std.range.primitives.isInputRange. When Contents is a struct, class, or an associative array, the element type of R is Contents, otherwise the element type of R is itself a range with element type Contents. The returned range provides aheader
field for accessing theheader
from theinput
in array form.string str = "a,b,c\nHello,65,63.63"; auto records = csvReader(str, ["a"]); assert(records.header == ["a","b","c"]);
Throws:CSVException When aquote
is found in an unquoted field, data continues after a closingquote
, the quoted field was not closed before data was empty, a conversion failed, or when the row's length does not match the previous length. HeaderMismatchException when aheader
is provided but a matching column is not found or the order did not match that found in theinput
. Read the exception documentation for specific details of when the exception is thrown for different types of Contents. - auto
csvReader
(Contents = string, Malformed ErrorLevel = Malformed.throwException, Range, Header, Separator = char)(Rangeinput
, Headerheader
, Separatordelimiter
= ',', Separatorquote
= '"')
if (isInputRange!Range && is(Unqual!(ElementType!Range) == dchar) && isSomeChar!Separator && is(Header : typeof(null))); - void
csvNextToken
(Range, Malformed ErrorLevel = Malformed.throwException, Separator, Output)(ref Rangeinput
, ref Outputans
, Separatorsep
, Separatorquote
, boolstartQuoted
= false)
if (isSomeChar!Separator && isInputRange!Range && is(Unqual!(ElementType!Range) == dchar) && isOutputRange!(Output, dchar)); - Lower level control over parsing CSVThis function consumes the
input
. After each call theinput
will start with either a delimiter or record break (\n, \r\n, \r) which must be removed for subsequent calls.Parameters: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 specificationbool startQuoted
Whether the input
should be considered to already be in quotesThrows:IncompleteCellException When aquote
is found in an unquoted field, data continues after a closingquote
, or the quoted field was not closed before data was empty.Examples:import std.array : appender; import std.range.primitives : popFront; string str = "65,63\n123,3673"; auto a = appender!(char[])(); csvNextToken(str,a,',','"'); writeln(a.data); // "65" writeln(str); // ",63\n123,3673" str.popFront(); a.shrinkTo(0); csvNextToken(str,a,',','"'); writeln(a.data); // "63" writeln(str); // "\n123,3673" str.popFront(); a.shrinkTo(0); csvNextToken(str,a,',','"'); writeln(a.data); // "123" writeln(str); // ",3673"
Copyright © 1999-2017 by the D Language Foundation | Page generated by
Ddoc on (no date time)