CSV stands for comma-separated values, a plain-text format for a table. Each line is one row, called a record, and commas separate the values in it, called fields. Spreadsheets such as Excel and Google Sheets can save a sheet as CSV and open one, and many apps offer a CSV export, which makes it a common way to move a table from one program to another.
Commas are the trouble. A cell holding Pens, blue can't be written as it is, or it would read as two fields, Pens and blue. So a field that contains a comma is wrapped in double quotes, and inside the quotes, a comma is part of the value. That makes a double quote special in turn: inside a quoted field, a lone " would look like the closing quote. So a field that contains a " is quoted as well, and each " in it is written twice, as "".
Here's one row as a spreadsheet shows it, and how the CSV file writes each cell:
| Cell in the spreadsheet | Written in the CSV file | Why |
|---|---|---|
Pens, blue | "Pens, blue" | Quoted, so its comma isn't a separator. |
12" ruler | "12"" ruler" | Quoted, with its " written twice. |
3.50 | 3.50 | Nothing special in it, so no quotes. |
The whole row is the line "Pens, blue","12"" ruler",3.50. It has three commas, but only the two outside quotes separate fields, so it holds three fields. The quotes around a field aren't part of its value, and "" inside one stands for a single ".
There's no single official standard; the closest is RFC 4180, which describes the form shown here. It also lets a quoted field contain a line break, so one record can take up more than one line of the file. Programs differ in the details: Excel, for example, uses semicolons instead of commas where the comma is the decimal separator, as it is in much of Europe.
Write parseCsvLine(line). It splits one line of CSV (comma-separated values) into an array of field strings.
Fields are separated by commas. Every comma outside quotes starts a new field, so a line with n such commas has n + 1 fields, and empty fields are kept: a,,b, gives ["a", "", "b", ""], and an empty line gives [""].
A field is quoted when its first character is ". A quoted field ends at the next " that isn't doubled; inside it, commas are ordinary characters and "" stands for one ". The surrounding quotes aren't part of the value. After the closing quote, the next character must be a comma or the end of the line.
Any other field is unquoted and kept exactly as written, spaces and " characters included. Throw a SyntaxError if a quoted field never closes, or if anything other than a comma follows its closing quote.
parseCsvLine('Ada,"Lovelace, Ada",36');
// ["Ada", "Lovelace, Ada", "36"]
parseCsvLine('"She said ""hi""",,x');
// ['She said "hi"', "", "x"]
parseCsvLine(' 5" , b ');
// [' 5" ', " b "]
parseCsvLine('"never closed, oops'); // throws a SyntaxError
expect(parseCsvLine("a,b,c")).toEqual(["a", "b", "c"]);
expect(parseCsvLine("one")).toEqual(["one"]);
expect(parseCsvLine("a,,b,")).toEqual(["a", "", "b", ""]);
expect(parseCsvLine(",x")).toEqual(["", "x"]);
expect(parseCsvLine(",")).toEqual(["", ""]);
expect(parseCsvLine("")).toEqual([""]);
expect(parseCsvLine('Ada,"Lovelace, Ada",36')).toEqual(["Ada", "Lovelace, Ada", "36"]);
expect(parseCsvLine('",,",","')).toEqual([",,", ","]);
expect(parseCsvLine('"She said ""hi""",x')).toEqual(['She said "hi"', "x"]);
expect(parseCsvLine('""""')).toEqual(['"']);
expect(parseCsvLine('"a""b"')).toEqual(['a"b']);
expect(parseCsvLine('""')).toEqual([""]);
expect(parseCsvLine('a,"",b')).toEqual(["a", "", "b"]);
expect(parseCsvLine('"",""')).toEqual(["", ""]);
expect(parseCsvLine(' a , b"c ,5"')).toEqual([" a ", ' b"c ', '5"']);
expect(parseCsvLine(' "x",y')).toEqual([' "x"', "y"]);
expect(() => parseCsvLine('"abc,def')).toThrow(SyntaxError);
expect(() => parseCsvLine('a,"b""')).toThrow(SyntaxError);
expect(() => parseCsvLine('"')).toThrow(SyntaxError);
expect(() => parseCsvLine('"a"b,c')).toThrow(SyntaxError);
expect(() => parseCsvLine('x,"a" ,c')).toThrow(SyntaxError);
Run tests runs every test on your code, here in your browser. The problem is solved when they all pass.
Ctrl + Enter runs the tests (⌘ + Enter on a Mac).
I'm here to help with Parse a CSV line. I give hints, never the solution, so you get to solve it yourself. Ask for a hint, select code to ask about it, or press Ask Tuto why on a failing test.
Your first 3 answers need no account. for free to keep asking.