Ré-écriture de l'algo

This commit is contained in:
laurentu 2024-08-07 15:46:14 +02:00
parent 5f6ef91d86
commit 614ec535aa
2 changed files with 52 additions and 39 deletions

View File

@ -37,50 +37,55 @@ func (p *CsvParser) Initialize(delimiter string, enclosers []string, lineFormat
} }
func (p *CsvParser) Parse(line string) (map[string]string, error) { func (p *CsvParser) Parse(line string) (map[string]string, error) {
inEnclosedField := false
currentEncloserEnd := ' '
escape := false
currentFieldIndex := 0 currentFieldIndex := 0
valueStart := 0
escape := false
enclosed := false
ret := make(map[string]string) ret := make(map[string]string)
valueStart := 0
indexMax := len(line) - 1 indexMax := len(line) - 1
maxFieldIndex := len(p.fields) - 1
delimiter := p.delimiter
for index, r := range line { for index, r := range line {
if index == indexMax { if r == '\\' {
if currentFieldIndex < len(p.fields) && p.fields[currentFieldIndex] != "ignore" { // Check if EOL before continue
if inEnclosedField && r == currentEncloserEnd { escape=true
ret[p.fields[currentFieldIndex]] = line[valueStart:index] continue
} else { }
ret[p.fields[currentFieldIndex]] = line[valueStart : index+1] if escape {
} escape=false
} continue
} }
if r == '\\' { if r == delimiter {
escape = !escape ret[p.fields[currentFieldIndex]] = line[valueStart : index]
} else if inEnclosedField { currentFieldIndex++
if r == currentEncloserEnd && !escape { if currentFieldIndex > maxFieldIndex {
inEnclosedField = false break
} }
} else if r == p.delimiter { valueStart = index + 1
if enclosed {
if currentFieldIndex < len(p.fields) && p.fields[currentFieldIndex] != "ignore" { enclosed=false
ret[p.fields[currentFieldIndex]] = line[valueStart:index] delimiter = p.delimiter
valueStart = index + 1 // Omit next delimiter
} escape=true
currentFieldIndex++ }
} else { continue
for _, encloser := range p.enclosers { }
runes := []rune(encloser) if index >= indexMax {
if r == runes[0] { ret[p.fields[currentFieldIndex]] = line[valueStart:]
// opening encloser continue
inEnclosedField = true }
currentEncloserEnd = runes[1]
valueStart++
break
}
}
}
}
for _, encloser := range p.enclosers {
runes := []rune(encloser)
if r == runes[0] {
// opening encloser
enclosed = true
delimiter = runes[1]
valueStart++
break
}
}
}
return ret, nil return ret, nil
} }

View File

@ -48,6 +48,14 @@ func TestCorrectLines(t *testing.T) {
} }
fmt.Println("event is", event) fmt.Println("event is", event)
line = "John Doe \"John Doe\"\\\\"
fmt.Println("parsing:", line)
event, err = csvParser.Parse(line)
if err != nil {
t.Fatalf("Parsing of empty line failed %v %v", err, event)
}
fmt.Println("event is", event)
line = "John Doe I don't know him" line = "John Doe I don't know him"
fmt.Println("parsing:", line) fmt.Println("parsing:", line)
event, err = csvParser.Parse(line) event, err = csvParser.Parse(line)