CSV 格式说明和应用

问题

我们常常将多个字符串item使用逗号拼接成一个字符串,用来表示数组,使用时再用逗号切割成为数组。比如安卓机型列表:

ALN-AL10,ALN-AL10,BRA-AL00,ALN-AL00/ALN-AL80

直到有一天,苹果设备也要用到这个机型列表,而它的每个机型都带着逗号,那我们使用逗号切割就得到了错误的数据。

iPhone15: iPhone15,4
iPhone15Plus: iPhone15,5
iPhone15Pro: iPhone16,1
iPhone15Pro_Max: iPhone16,2

为了解决这个问题,首先想到了换一个分隔符,比如 | ,再比如用一些不可见字符 : 0x01。
但我们不能保证这些字符串 item 一定不包含这些特殊字符,也许还有更好的方法。

既然是逗号分隔,首先想到的就是 CSV格式,毕竟 CSV 的全称就是Comma-Separated Values逗号分隔值。它是如何解决这个问题的?

CSV格式

CSV 的RFC说明文档:https://datatracker.ietf.org/doc/html/rfc4180

  1. 基本字段
  2. 包含逗号的字段,则使用双引号括起来;
  3. 包含双引号的字段,则在双引号前面必须加上另一个双引号进行转义。;
  4. 包含换行符的字段,则使用双引号括起来;
  5. 包含特殊字符的组合的字段,也是使用双引号括起来;
姓名,年龄,城市,备注
张三,30,北京,无备注
李四,25,上海,"喜欢, 打篮球"
王五,28,"广州, 广东",""
"李, 六",35,"""特别"" 市","这是一段
跨行的备注"
"陈, 七","40","深圳",

"包含""双引号""和,逗号"

使用 csv 的工具包是可以非常方便的处理这种数据。类似的后台表格导出 csv 文件也应当使用该csv工具包。

example:

Go 语言可以使用 https://pkg.go.dev/encoding/csv

func main() {
    in := `姓名,年龄,城市,备注
张三,30,北京,无备注
李四,25,上海,"喜欢, 打篮球"
王五,28,"广州, 广东",""
"李, 六",35,"""特别"" 市","这是一段
跨行的备注"
"陈, 七","40","深圳","包含""双引号""和,逗号"
`
    r := csv.NewReader(strings.NewReader(in))
    for {
        record, err := r.Read()
        if err == io.EOF {
            break
        }
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println(record)
    }
}

输出:

[姓名 年龄 城市 备注]
[张三 30 北京 无备注]
[李四 25 上海 喜欢, 打篮球]
[王五 28 广州, 广东 ]
[李, 六 35 "特别" 市 这是一段
跨行的备注]
[陈, 七 40 深圳 包含"双引号"和,逗号]
package utils

import (
	`bytes`
	`encoding/csv`
	`strings`
)

// SliceToCsvString 将字符串切片转换为CSV字符串
func SliceToCsvString(slice []string) (string, error) {
	var buf bytes.Buffer
	writer := csv.NewWriter(&buf)
	// 写入单行数据
	err := writer.Write(slice)
	if err != nil {
		return "", err
	}
	// 确保所有数据都被写入
	writer.Flush()
	// 检查是否有任何错误
	if err := writer.Error(); err != nil {
		return "", err
	}

	return buf.String(), nil
}

// CsvStringToSlice 将CSV字符串转换为字符串切片
func CsvStringToSlice(csvString string) ([]string, error) {
	reader := csv.NewReader(strings.NewReader(csvString))
	reader.ReuseRecord = true
	// 读取所有记录
	records, err := reader.Read()
	if err != nil {
		return nil, err
	}

	return records, nil
}

Read more

CLI 工具多版本管理器 - asdf

CLI 工具多版本管理器 - asdf

asdf 是一个 CLI 工具,可以根据每个项目管理多个工具或语言运行时版本。它就像 gvm、nvm、rbenv 和 pyenv(以及更多)的合一工具!只需安装您语言的插件即可! 这个随手起的名字,可能是目前地表最强版本管理器。 https://github.com/asdf-vm/asdf 一、安装 asdf 以 macbook 为示例 brew install asdf asdf -v asdf version 0.16.2 0.16.0 以上命令有较大变更,详见:https://asdf-vm.com/guide/upgrading-to-v0-16.html#breaking-changes 本文使用

By brian
golang proto api 校验国际化 protovalidate

golang proto api 校验国际化 protovalidate

众所周知,protobuf 原型文件扩展很多功能,比如生成 http 接口层代码,顺势就有了生成接口参数校验代码的需求。 早期可以使用https://github.com/bufbuild/protoc-gen-validate 来实现,通过生成特定的 go 代码的方式来实现校验。 github 中也提到目前趋于稳定,不会有更多新特性的支持,推荐大家使用新的版本 protovalidate,https://github.com/bufbuild/protovalidate 。该版本是protoc-gen-validate 的“精神继承者”。它不需要任何代码生成并支持自定义约束。 现在我们尝试新版本,并且增加国际化支持。 go get github.com/bufbuild/protovalidate-go import "github.com/bufbuild/protovalidate-go" syntax = "proto3"; package

By brian
沪ICP备2022013452号-1