Split one CSV line properly
An import job reads a CSV where some fields legitimately contain commas, so splitting on the comma alone corrupts the data.
- Commas separate fields, except inside a double-quoted field.
- Inside a quoted field, two double quotes in a row mean one literal quote.
- The quotes themselves are not part of the value.
- An empty line gives an empty list; an empty field between two commas gives an empty string.
parseCsvLine(line: string) → list<string>
Go needs a compiler and Drill does not host one yet, so this page is the reference rather than an exercise: the problem, worked examples, and the solution in full. To type it out, the same problem runs in Python.
Where you start
func parseCsvLine(line string) []string {
}
Worked examples
| Call | Result |
|---|---|
parseCsvLine("a,b,c") | []string{"a", "b", "c"} |
parseCsvLine("a,\"b,c\",d") | []string{"a", "b,c", "d"} |
parseCsvLine("\"say \"\"hi\"\"\",x") | []string{"say \"hi\"", "x"} |
parseCsvLine("a,,b") | []string{"a", "", "b"} |
Hint
Walk the line one character at a time carrying a single boolean: are we inside quotes right now.
Reference solution in Go
func parseCsvLine(line string) []string {
if line == "" {
return []string{}
}
fields := []string{}
cur := ""
quoted := false
i := 0
for i < len(line) {
c := line[i]
if quoted {
if c == '"' {
if i+1 < len(line) && line[i+1] == '"' {
cur += "\""
i += 2
continue
}
quoted = false
i++
continue
}
cur += string(c)
i++
} else if c == '"' {
quoted = true
i++
} else if c == ',' {
fields = append(fields, cur)
cur = ""
i++
} else {
cur += string(c)
i++
}
}
fields = append(fields, cur)
return fields
}