RFC 4180 (October 2005) describes
the format “that seems to be followed by most implementations” and registers
text/csv; it is informational, not a standard every program follows. W3C’s
CSV on the Web recommendations describe the variations. This page follows
RFC 4180,
RFC 7111,
Metadata Vocabulary for Tabular Data
and Model for Tabular Data and
Metadata on the Web, read 2026-11-12.
RFC 4180 grammar
file = [header CRLF] record *(CRLF record) [CRLF]
header = name *(COMMA name)
record = field *(COMMA field)
name = field
field = (escaped / non-escaped)
escaped = DQUOTE *(TEXTDATA / COMMA / CR / LF / 2DQUOTE) DQUOTE
non-escaped = *TEXTDATA
COMMA = %x2C
CR = %x0D
DQUOTE = %x22
LF = %x0A
CRLF = CR LF
TEXTDATA = %x20-21 / %x23-2B / %x2D-7E
- Records end with CR LF; the last one may or may not.
- Every record should have the same number of fields, and the last field must not be followed by a comma.
- A field containing a comma, a double quote or a line break should be in double
quotes; inside quotes a double quote must be written twice:
"say ""hi""". An unquoted field may not contain double quotes. - Spaces are part of a field and should not be ignored.
TEXTDATAallows only printable ASCII. RFC 4180 says common usage is US-ASCII, with other character sets named by thecharsetparameter; the W3C model notes that this restriction “is routinely ignored in practice”.
Media type
text/csv, with optional parameters charset (such as
utf-8) and header (present or
absent). RFC 7111 (January 2014, updates RFC 4180) adds fragment
identifiers for rows, columns and cells, such as #row=5-7,
#col=2 and #cell=4,1 (row 4, column 1); rows and columns
count from 1.
Dialects
W3C’s “Metadata Vocabulary for Tabular Data” (Recommendation, 17 December 2015) defines dialect descriptions, hints that tell a parser how to read a CSV file, with these defaults:
| Property | Default | Meaning |
|---|---|---|
encoding | "utf-8" | Character encoding, one defined in the Encoding specification. |
lineTerminators | ["\r\n", "\n"] | String or array of strings that end a row. |
delimiter | "," | Field separator. |
quoteChar | '"' | Quote character; null also sets the escape character to none. |
doubleQuote | true | If true the escape character is " (quotes doubled); if false it is a backslash. |
header | true | true sets the header row count to 1, false to 0; ignored when headerRowCount is given. |
headerRowCount | 1 | Number of header rows, a non-negative integer. |
skipRows | 0 | Rows to skip at the start of the file, before a header row or data. |
skipColumns | 0 | Columns to skip at the start of each row. |
commentPrefix | "#" | Prefix marking comment lines. |
skipBlankRows | false | Whether blank rows are ignored. |
skipInitialSpace | false | true sets trimming to "start"; ignored when trim is given. |
trim | true in the property list; false in the spec’s own default dialect example | true, false, "true", "false", "start" or "end". |
The two defaults for trim are both in section 5.9 of the
recommendation: the property definition says “The default is true”, while the
default dialect description printed under it has "trim": false. The
“Model for Tabular Data” also gives the trim flag a default of true.
Appendix B of the “Model for Tabular Data and Metadata on the Web” records how some
programs behaved when tested: Excel for Mac 2011 (English locale) saved CSV as
Windows-1252 with LF line endings, quoting only cells that need it and doubling
quotes, and read UTF-8 files as Windows-1252 whether or not a byte order mark was
present; Google Spreadsheets downloaded CSV as UTF-8 without a byte order mark, with
LF line endings. The model also has a text/tab-separated-values response
set the delimiter to tab (see TSV).