
本文介绍一种健壮、可扩展的 Go 实现方案,通过灵活解析多种键值对输入格式(如逗号/空格分隔、带引号值),并利用标准 encoding/json 库生成合法 JSON,避免手动拼接引发的安全与兼容性问题。
本文介绍一种健壮、可扩展的 go 实现方案,通过灵活解析多种键值对输入格式(如逗号/空格分隔、带引号值),并利用标准 `encoding/json` 库生成合法 json,避免手动拼接引发的安全与兼容性问题。
在 Go 开发中,将原始键值对字符串(如 id=1 name=peter age="12")转换为标准 JSON 是常见需求。但直接使用正则替换(如 fmt.Sprintf("{%s}", regex.ReplaceAllString(...)))存在严重隐患:无法正确处理嵌套引号、转义字符、空格边界及类型歧义,且生成的字符串不是真正可解析的 JSON(例如 {"id"="1"} 语法错误,合法 JSON 要求键和字符串值必须用双引号包裹,且键值间用冒号 : 分隔)。
✅ 正确做法是 “解析 → 结构化 → 序列化”三步分离:
-
安全解析:按分隔符(
,或空格)切分字段,再以=拆分键值; -
智能清洗:自动去除值两端的双引号(如
"12"→12),保留内部转义(如"a\"b"→a"b); -
标准序列化:交由
json.Marshal()生成符合 RFC 8259 的 JSON 字节流。
以下为生产就绪的实现:
package main
import (
"encoding/json"
"errors"
"fmt"
"strings"
)
// parseKV 解析键值对字符串为 map[string]string,支持逗号/空格分隔,并自动清理引号
func parseKV(s string) (map[string]string, error) {
data := make(map[string]string)
// 统一分隔符:将逗号+空格替换为空格,再按空格分割(兼容两种格式)
s = strings.ReplaceAll(s, ", ", " ")
fields := strings.Fields(s) // 自动跳过连续空格
for _, field := range fields {
if !strings.Contains(field, "=") {
return nil, errors.New("invalid field: missing '='")
}
pair := strings.SplitN(field, "=", 2) // 仅分割第一个=,支持值含=的情况
key := strings.TrimSpace(pair[0])
value := strings.TrimSpace(pair[1])
// 去除值两端的双引号(若存在),并正确处理内部转义
if len(value) >= 2 && value[0] == '"' && value[len(value)-1] == '"' {
unquoted, err := strconv.Unquote(`"` + value + `"`)
if err != nil {
return nil, fmt.Errorf("failed to unquote value %q: %w", value, err)
}
value = unquoted
}
data[key] = value
}
return data, nil
}
// 注意:需导入 "strconv" 包以使用 strconv.Unquote
// import "strconv"
func main() {
testCases := []string{
`id=1, name=peter, age=12`,
`id=1, name=peter, age="12"`,
`id=1 name=peter age=12`,
`id=1 name="peter pan" age="\"escaped\" quote"`,
}
for i, input := range testCases {
parsed, err := parseKV(input)
if err != nil {
fmt.Printf("❌ Parse error [%d]: %v\n", i, err)
continue
}
jsonBytes, err := json.Marshal(parsed)
if err != nil {
fmt.Printf("❌ Marshal error [%d]: %v\n", i, err)
continue
}
fmt.Printf("✅ [%d] Input: %s\n Output: %s\n", i, input, string(jsonBytes))
}
}? 关键注意事项:
-
绝不手写 JSON:
json.Marshal()自动处理引号转义、Unicode 编码、类型校验,避免 XSS 或解析失败; -
引号清洗要严谨:使用
strconv.Unquote安全解包带引号字符串(支持\"、\n等转义),而非简单strings.Trim(value,"); -
分隔符鲁棒性:
strings.Fields()自动处理多空格/制表符,比正则更稳定; -
错误即刻返回:对非法格式(如缺失
=)立即报错,避免静默数据污染。
此方案已覆盖原始需求的所有变体(逗号分隔、空格分隔、带引号值),并具备良好的可维护性——新增格式只需扩展 parseKV 内部逻辑,无需改动序列化层。


















