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..]
|
||||
continue
|
||||
} 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
|
||||
keep_raw = true
|
||||
continue
|
||||
|
@ -153,12 +170,12 @@ fn (mut r Reader) read_record() ?[]string {
|
|||
line = line[1..]
|
||||
if j + 1 == line.len {
|
||||
// last record
|
||||
fields << line[..j]
|
||||
fields << if has_double_quotes { line[..j].replace('""', '"') } else { line[..j] }
|
||||
break
|
||||
}
|
||||
next := line[j + 1]
|
||||
if next == r.delimiter {
|
||||
fields << line[..j]
|
||||
fields << if has_double_quotes { line[..j].replace('""', '"') } else { line[..j] }
|
||||
if j + 2 == line.len {
|
||||
line = ''
|
||||
} else {
|
||||
|
|
|
@ -227,3 +227,27 @@ fn test_field_quotes_for_parts() {
|
|||
}
|
||||
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