Skip to main content
All coding problems

Parse a CSV Line

MediumparsingState machine / single-pass scanstringsmediumparsing

Maintained by Vikas D, software engineer

You are given a single line of comma-separated values as a string. The task is to break it into the individual field values it contains. A plain comma in the line marks the boundary between two fields.

Any field may be wrapped in double quotes. When a field is quoted, commas inside the quotes are part of the value rather than separators, so a quoted field can hold commas without being split. The quote characters themselves are markers and never belong in the returned value.

Return the fields in order, with the surrounding quotes removed. You do not need to handle escaped quotes (a doubled quote pair) inside a quoted field, and the input contains only printable ASCII.

An empty input string represents one line with a single empty field, so the result is a list holding one empty string.

Examples

Input: "one,two,three"
Output: ["one", "two", "three"]

No quotes appear, so the two commas split the line into three plain fields.

Input: "\"hello, world\",foo"
Output: ["hello, world", "foo"]

The first field is quoted, so its inner comma stays inside the value; the quotes are stripped, then the unquoted comma separates the second field.

Input: "a,,b"
Output: ["a", "", "b"]

Two commas with nothing between them produce an empty middle field rather than collapsing.

Constraints

  • 0 <= line.length <= 10^4
  • Only printable ASCII characters appear in line.
  • Quoted fields never contain an escaped (doubled) quote, so each quote toggles in or out of quoted mode.
  • An empty string returns a single empty field, not an empty list.

Visible test cases

  • parseCSVLine("one,two,three") == ["one","two","three"]
  • parseCSVLine("\"hello, world\",foo") == ["hello, world","foo"]
  • parseCSVLine("a,\"b,c,d\",e") == ["a","b,c,d","e"]
  • parseCSVLine("single") == ["single"]
  • parseCSVLine("\"quoted\"") == ["quoted"]
  • parseCSVLine("a,,b") == ["a","","b"]

Hints

Hint 1

Walk the string one character at a time and build the current field as you go, instead of trying to split on commas all at once.

Hint 2

Keep a boolean flag for whether you are currently inside a quoted region. A comma only ends a field when that flag is off.

Hint 3

When you see a quote, flip the flag and add nothing to the value. Always push the field you have accumulated when you hit a separating comma or reach the end of the line.

Loading the editor...

Approaches

Naive split on comma

Time O(n) · Space O(n)

Splitting the whole line on commas is the obvious first instinct, but it tears quoted fields apart, so it only works once you stitch the broken pieces back together by tracking quote balance.

  1. Split the line on every comma into raw pieces.
  2. Scan the pieces left to right, counting quote characters to know when you are inside a quoted field.
  3. While the quote count is odd, keep rejoining the next piece with a comma to repair the field that was wrongly split.
  4. Strip surrounding quotes from each rebuilt field and collect the values.

Single-pass state machine

Time O(n) · Space O(n)

Scan once with a flag that records whether you are inside quotes. A comma is a separator only when the flag is off, and a quote just toggles the flag and is never copied into the value.

  1. Start with an empty current field, an empty result list, and inQuotes set to false.
  2. For each character: if inside quotes, a quote turns the flag off, anything else appends to the field.
  3. If outside quotes, a quote turns the flag on, a comma pushes the current field and resets it, any other character appends.
  4. After the loop, push the final field so the last value (and the empty-string case) is included.

Common mistakes

  • Splitting on commas without quote awareness shreds a field like "b,c,d" into separate pieces.
  • Forgetting to push the final accumulated field after the loop drops the last value, and also returns an empty list for an empty input instead of one empty string.
  • Stripping quotes only from the start and end of a field misfires when the value happens to contain a quote-like character; toggle on every quote instead.
  • Treating consecutive commas as one separator collapses a,,b into two fields rather than keeping the empty middle field.

Follow-up variations

  • Support escaped quotes inside a quoted field, where a doubled quote represents one literal quote character.
  • Parse a full multi-line CSV document where a quoted field may contain a newline that should not end the row.
  • Allow a configurable delimiter such as a tab or semicolon instead of a fixed comma.
  • Trim surrounding whitespace around unquoted fields while preserving it inside quoted ones.

Build the rest of your prep