From 9f83b3ce1fa14f32b13ecec20ea7c1672ef88d18 Mon Sep 17 00:00:00 2001 From: laurentu Date: Wed, 7 Aug 2024 16:19:17 +0200 Subject: [PATCH] =?UTF-8?q?Penser=20=C3=A0=20g=C3=A9rer=20le=20case=20de?= =?UTF-8?q?=20d=C3=A9limiteurs=20multiples=20qui=20s'encha=C3=AEnent=20et?= =?UTF-8?q?=20qui=20ne=20doivent=20=C3=AAtre=20pris=20en=20compte=20que=20?= =?UTF-8?q?pour=201=20seul?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- csvparser.go | 116 +++++++++++++++++++++++++-------------------------- 1 file changed, 57 insertions(+), 59 deletions(-) diff --git a/csvparser.go b/csvparser.go index 24d0aa2..6a26b20 100644 --- a/csvparser.go +++ b/csvparser.go @@ -7,28 +7,22 @@ import ( ) type CsvParser struct { - enclosers []string - delimiter rune - fields []string + enclosers []string + delimiters string + fields []string } -func (p *CsvParser) Initialize(delimiter string, enclosers []string, lineFormat string) error { - if utf8.RuneCountInString(delimiter) != 1 { - return fmt.Errorf("delimiter shoud be one character") +func (p *CsvParser) Initialize(delimiters string, enclosers []string, lineFormat string) error { + if utf8.RuneCountInString(delimiter) == 0 { + return fmt.Errorf("delimiter shoud be at least one character") } - p.enclosers = make([]string, 0) + p.delimiters = delimiters for _, encloser := range enclosers { if utf8.RuneCountInString(encloser) != 2 { return fmt.Errorf("encolser should have to characters") } } p.enclosers = enclosers - p.delimiter = []rune(delimiter)[0] - for _, pair := range enclosers { - if utf8.RuneCountInString(pair) != 2 { - return fmt.Errorf("encoloser should contain two characters: %s", pair) - } - } // line format is in the form of: field1 field2 ignore ... // if field name is ignore, it is parsed but not retained p.fields = strings.Split(lineFormat, " ") @@ -40,56 +34,60 @@ func (p *CsvParser) Parse(line string) (map[string]string, error) { currentFieldIndex := 0 valueStart := 0 escape := false - enclosed := false + enclosed := false ret := make(map[string]string) indexMax := len(line) - 1 - maxFieldIndex := len(p.fields) - 1 - delimiter := p.delimiter + maxFieldIndex := len(p.fields) - 1 + delimiters := p.delimiters for index, r := range line { - if r == '\\' { - // Check if EOL before continue - escape=true - continue - } - if escape { - escape=false - continue - } - if r == delimiter { - if p.fields[currentFieldIndex] != "ignore" { - ret[p.fields[currentFieldIndex]] = line[valueStart : index] - } - currentFieldIndex++ - if currentFieldIndex > maxFieldIndex { - break - } - valueStart = index + 1 - if enclosed { - enclosed=false - delimiter = p.delimiter - // Omit next delimiter - escape=true - } - continue - } - if index >= indexMax { - if p.fields[currentFieldIndex] != "ignore" { - ret[p.fields[currentFieldIndex]] = line[valueStart:] - } - continue - } + if r == '\\' { + // Check if EOL before continue + escape = true + continue + } + if escape { + escape = false + continue + } + for _, d := range delimiters { + delimiter = true + } + if delimiter { + if p.fields[currentFieldIndex] != "ignore" { + ret[p.fields[currentFieldIndex]] = line[valueStart:index] + } + currentFieldIndex++ + if currentFieldIndex > maxFieldIndex { + break + } + valueStart = index + 1 + if enclosed { + enclosed = false + delimiter = p.delimiter + // Omit next delimiter + escape = true + } + continue + } - for _, encloser := range p.enclosers { - runes := []rune(encloser) - if r == runes[0] { - // opening encloser - enclosed = true - delimiter = runes[1] - valueStart++ - break - } - } - } + if index >= indexMax { + if p.fields[currentFieldIndex] != "ignore" { + ret[p.fields[currentFieldIndex]] = line[valueStart:] + } + continue + } + + for _, encloser := range p.enclosers { + runes := []rune(encloser) + if r == runes[0] { + // opening encloser + enclosed = true + delimiters = runes[1] + valueStart++ + break + } + } + } return ret, nil }