Doppelte Anführungszeichen CSV-Elemente in Golang

Was du machen willst

Aus Allgemeines Format der CSV-Datei (japanische Übersetzung RFC4180)

Jedes Feld (im Datensatz) kann in doppelte Anführungszeichen gesetzt werden oder nicht

Es gibt eine Aussage, also lasst sie uns je nach Projekt in doppelte Anführungszeichen setzen! Ich denke, dass es passieren kann. Bei mir war es genauso.

Wie der Titel schon sagt, wird ** Golang jedes Element von csv doppelt zitieren! ** Das möchte ich diesmal machen.

Beim Standard-CSV-Encoder von Golang wird "" jedoch immer als Escape-Zeichen hinzugefügt, sodass es zu "" Spalte "" → "" "Spalte" "" wird. Was ist los

Fazit

Verwenden Sie grundsätzlich gocsv. Verarbeitung so codieren, die Ausgabe ist wie folgt.

client_id,client_name,client_age
12,John,21
13,Fred,
14,James,32
15,Danny,
Vollständiger Code

base.go


package main

import (
	"fmt"
	"bytes"

	"github.com/gocarina/gocsv"
)

type Client struct { // Our example struct, you can use "-" to ignore a field
	Id      string `csv:"client_id"`
	Name    string `csv:"client_name"`
	Age     string `csv:"client_age"`
	NotUsed string `csv:"-"`
}

//base data
func basedata() []*Client {
	clients := []*Client{}
	clients = append(clients, &Client{Id: "12", Name: "John", Age: "21"}) // Add clients
	clients = append(clients, &Client{Id: "13", Name: "Fred"})
	clients = append(clients, &Client{Id: "14", Name: "James", Age: "32"})
	clients = append(clients, &Client{Id: "15", Name: "Danny"})
	return clients
}

func main() {
	clients := basedata()
	out := bytes.Buffer{}
	err := gocsv.Marshal(&clients, &out) // Get all clients as CSV string
	if err != nil {
		panic(err)
	}
	csvContent := out.Bytes()
	fmt.Println(string(csvContent)) // Display all clients as CSV string

}

Unabhängig davon, wie viel Sie vor dem Codieren an jedes Element anhängen, wird es von Marshal in "" geändert. Ändern Sie also Ihre Einstellung. Sobald Sie die codierte Byte-Zeichenfolge dekodiert haben, können Sie sie als Zeichenfolge für jedes Element abrufen. Fügen Sie also "" hinzu.

Da gocsv Trennzeichen und Zeilenvorschubcodes steuern kann, wird es von dort übernommen.

Standardmäßig ist es der Wert von "gocsv.SafeCSVWriter", der durch Ausführen von "gocsv.DefaultCSVWriter" erhalten werden kann, also ",". Der Zeilenvorschubcode lautet "\ n".

Diese Informationen können sich mit gocsv.SetCSVWriter ändern. Bitte ändern Sie sie entsprechend Ihrer Implementierung.

Das Beispiel ist hier, und die Verarbeitung ist ein Auszug. Gist

base.go


//Übergeben Sie das zweite Argument des Marschalls so wie es ist
func convert(b *bytes.Buffer) ([]byte, error) {
        //retry to decode, to check ""
        reader := csv.NewReader(b)
        reader.LazyQuotes = true
        lines, err := reader.ReadAll()
        if err != nil {
                return []byte{}, err
        }

        //rewrite to add "", escape \"
        bytes := make([]byte, 0, len(b.Bytes())*2)

        //If you update writer by SetCSVWriter, please change the delimiter which you use
        delimiter := ','
        //If you update writer by SetCSVWriter, please change the crlf which you use
        for _, line := range lines {
                for i, part := range line {
                        if i != 0 {
                                bytes = append(bytes, byte(delimiter))
                        }
                        bytes = append(bytes, []byte(escape(part))...)
                }
                bytes = append(bytes, byte('\r'))
        }
        return bytes, nil
}

func escape(part string) string {
        //"XXX" => XXX
        escapeStr := strings.Replace(part, "\"", "\"\"", -1)
        return "\"" + escapeStr + "\""
}

Ausführungsergebnis. Wenn Sie das Tag unverändert lassen möchten, können Sie die Linienschleife beim Konvertieren anpassen und den Anfang überspringen.

"client_id","client_name","client_age"
"12","John","21"
"13","Fred",""
"14","James","32"
"15","Danny",""
Bonus
## Bonus Hintergrund zum Abschluss

Genießen Sie den Samstagabend des Onkels, der darum kämpft, CSV in Golang zu implementieren

Auslöser: Es gab eine Geschichte mit der Aufschrift "Ich kann mit doppelten CSV-Zitaten nicht umgehen!", Also habe ich sie untersucht.

Wenn ich den Referenzartikel als Hinweis verwende, frage ich mich, ob es eine gute Idee wäre, ihn irgendwo in den Encoder zu packen. Unten ist der Ablauf der Schlammuntersuchung

  • Kann ich "SetCSVWriter" in gocsv verwenden, um "csv.Writer" in io.Writer und "encoding / csv" zu überschreiben?
  • Da io.Writer die Byte-Zeichenfolge steuert, unterscheidet sich das Erstellen eines eigenen CSV-Parsers nicht vom Erstellen eines eigenen CSV-Parsers. Abgelehnt
  • Da die Codierungs- / CSV-Seite die intern definierte Struktur anstelle der Schnittstelle austauscht, ist es aufgrund der Spezifikationen von Golang unmöglich, diese zu überschreiben.
  • → Diese Idee ist nutzlos!
  • Können Sie im Gegenteil den von gocsv verwendeten Writer ändern und verschiedene Prozesse ausführen, um " hinzuzufügen? --Gocsv definiert eine Schnittstelle namens "CSVWriter"! Es sieht so aus, als ob es verwendet werden kann! ――Nein, es ist möglich, die Writer-Generierungsfunktion bei SetCSVWriter zu registrieren, aber das Argument der Funktion lautet "* SafeCSVWriter" anstelle von "CSVWriter". Die Form passt nicht. .. .. ――Aber was die Verwendung von gocsv betrifft, verwende ich keinen anderen SafeCSVWriter als die Schnittstelle von CSVWriter! Funktioniert es auch, wenn die Definition in CSVWriter geändert wird?
  • Gabel und versuchen Sie, CSVWriter zu überschreiben. Oh, ich kann gehen! ――Bitte packen Sie den Beispielcode in doppelten Anführungszeichen! Es wäre großartig, wenn Sie es offiziell einbauen könnten. Möchten Sie einen Test in einem tatsächlichen Fall schreiben, indem Sie Ihren eigenen CSVWriter bewegen? ――Wow, das damit festgelegte doppelte Anführungszeichen ist entkommen! ―― Bisher sieht es gut aus, aber es scheint, dass es nicht gelöst werden kann
  • Die Dekodierung von gocsv ist gut im Umgang "Sie können Daten für jedes Element erhalten!
  • Wenn Sie dann den oben angegebenen doppelten Anführungszeichencode in Spalteneinheiten herausnehmen, können Sie die Zeichen erhalten, ohne zu entkommen! Sollten wir dies nicht verwenden, um in "[] Byte" zu schreiben und es neu zu erstellen? --Ja du kannst. Das "Escape" in der Zeichenfolge fehlt ebenfalls, also fügen wir es hinzu! --OK! Es ging gut! Stellen Sie nach einer Pause eine PR auf gocsv heraus und es ist eine Lösung! -... das, ist es nicht bedeutungslos, mit CSVWriter zu spielen?

Es war Saturday Night Fever, der den offiziellen Code debuggte und reparierte, der vergebens endete.

Ich habe mich gefragt, ob ich die Spuren meiner Bemühungen veröffentlichen würde, aber ich dachte, es lohnt sich nicht, weil die Anzahl der Anwendungsfälle Null wurde, also habe ich sie auf Eis gelegt. Am Ende schrieb ich diesen Artikel und stattdessen Gist auf

Referenz

Allgemeines Format der CSV-Datei (japanische Übersetzung RFC4180) 4.1.6 Beschreibungsregeln für das CSV-Format Bei der Ausgabe von CSV mit Golang können Elemente nicht in doppelte Anführungszeichen gesetzt werden gocsv Beamter

Recommended Posts