csv: fix csv fields with double quotes (#10399)
parent
10b9ea3258
commit
9a9d539e6f
|
@ -145,7 +145,24 @@ fn (mut r Reader) read_record() ?[]string {
|
||||||
line = line[i + 1..]
|
line = line[i + 1..]
|
||||||
continue
|
continue
|
||||||
} else { // quoted
|
} else { // quoted
|
||||||
j := line[1..].index('"') or {
|
mut need_more := true
|
||||||
|
mut has_double_quotes := false
|
||||||
|
mut j := 0
|
||||||
|
mut n := 1
|
||||||
|
for n < line.len {
|
||||||
|
if line[n] == `"` {
|
||||||
|
if n == line.len - 1 || line[n + 1] != `"` {
|
||||||
|
need_more = false
|
||||||
|
j = n - 1
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
has_double_quotes = true
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
if need_more {
|
||||||
need_read = true
|
need_read = true
|
||||||
keep_raw = true
|
keep_raw = true
|
||||||
continue
|
continue
|
||||||
|
@ -153,12 +170,12 @@ fn (mut r Reader) read_record() ?[]string {
|
||||||
line = line[1..]
|
line = line[1..]
|
||||||
if j + 1 == line.len {
|
if j + 1 == line.len {
|
||||||
// last record
|
// last record
|
||||||
fields << line[..j]
|
fields << if has_double_quotes { line[..j].replace('""', '"') } else { line[..j] }
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
next := line[j + 1]
|
next := line[j + 1]
|
||||||
if next == r.delimiter {
|
if next == r.delimiter {
|
||||||
fields << line[..j]
|
fields << if has_double_quotes { line[..j].replace('""', '"') } else { line[..j] }
|
||||||
if j + 2 == line.len {
|
if j + 2 == line.len {
|
||||||
line = ''
|
line = ''
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -227,3 +227,27 @@ fn test_field_quotes_for_parts() {
|
||||||
}
|
}
|
||||||
assert row_count == 4
|
assert row_count == 4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_field_double_quotes() {
|
||||||
|
row1 := '11,"12\n13"\n'
|
||||||
|
row2 := '21,"2""2""\n23"\n'
|
||||||
|
row3 := '"3""1""",32\n'
|
||||||
|
data := row1 + row2 + row3
|
||||||
|
mut csv_reader := csv.new_reader(data)
|
||||||
|
mut row_count := 0
|
||||||
|
for {
|
||||||
|
row := csv_reader.read() or { break }
|
||||||
|
row_count++
|
||||||
|
if row_count == 1 {
|
||||||
|
assert row[0] == '11'
|
||||||
|
assert row[1] == '12\n13'
|
||||||
|
} else if row_count == 2 {
|
||||||
|
assert row[0] == '21'
|
||||||
|
assert row[1] == '2"2"\n23'
|
||||||
|
} else if row_count == 3 {
|
||||||
|
assert row[0] == '3"1"'
|
||||||
|
assert row[1] == '32'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert row_count == 3
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue