Help us understand the problem. What is going on with this article?

【作りたいもの】golangでLCSVパーサ

More than 1 year has passed since last update.

メモ

LCSV (Labeled-CSV) のパーサがほしい
できればstruct tagのパースできるやつ

使い方は2種類あって、CSVパーサみたいに各行パースするやつと、JSON的にワンライナーの文字列をパースするやつ。

イメージ(csvと同じ感じで)

values := `name: John, country: US, sex: male
name: Hana, country: JP, sex: female
name: Kim, country: CH`

var datum map[string]string
var err error
reader := lcsv.NewReader(strings.NewReader(values))
for err == nil {
    datum, err = reader.Read()
    fmt.Println(datum)
}
/* Output:
map[name:John country:US sex:male]
map[name:Hana country:JP sex:female]
map[name:Kim country:CH]
*/

イメージ(jsonな使い方)

GoのStruct Tagは、tagName:"HOST_NAME,required,default=example.com"みたいな書かれ方しがち。
tagName をキーに HOST_NAME,required,default=example.com はカンタンに取得できるけど、
中身は各々勝手にルール決めてパースしてる感じ。
でも要はこれLCSVだよねと思うので、"クォーテーションできない(Unquoted)"、"値とラベルの区切り文字が= (LabelSeparator('='))とかオプション指定できれば、json.Decoderみたいにやれそう。

var key string
var options map[string]string
tagValue := `required,default=example.com`
decoder := lcsv.NewDecoder(lcsv.Separator(','), lcsv.Unquoted(), lcsv.LabelSeparator('='))
if err := decoder.Decode(tagValue, options); err != nil {
    panic(err)
}
fmt.Println(options)
/* Output:
map[required: default:example.com]
*/

メンドクサポイント

エスケープシーケンス。
CSVのあれは控えめに言ってうんこだから実装したくない。
\ (backslash) でいいじゃん。

kyoh86
Golangとzshとvimをこよなく愛するふとっちょプログラマーです。
https://kyoh86.dev/
wacul
人工知能でWebサイトの課題を発見する AIアナリスト https://wacul-ai.com を開発しています
https://wacul.co.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away