Golang将数据格式化为JSON格式

时间:2017-04-27 21:26:25

标签: json regex go formatting string-formatting

我的原始数据格式:

id=1, name=peter, age=12

我将其转换为JSON字符串:

{"id" : "1", "name" : "peter", "age" : "12"}

我使用以下golang语句进行转换:

Regex, err = regexp.Compile(`([^,\s]*)=([^,\s]*)`)  
JSON := fmt.Sprintf("{%s}", Regex.ReplaceAllString(inp, `"$1" : "$2"`))

inp是保存原始数据格式的变量。

然而,现在我得到了一种新格式:

id=1 name=peter age=12

我还想使用我上面使用的类似方法转换为JSON字符串,即使用正则表达式进行一次格式化。

{"id"="1", "name"="peter", "age"="12"}

我怎样才能做到这一点?

更新:一项额外要求。如果输入格式是

id=1, name=peter, age="12"

我需要摆脱“”或“逃脱”,以便我可以在下一步处理。双引号可以出现在任何值字段的开头和结尾。

1 个答案:

答案 0 :(得分:1)

问题分为两个部分:简单部分是序列化为JSON,Go有standard library方法可以做到这一点。我会使用该库而不是尝试自己编码JSON。

您的问题稍微棘手的部分是将输入解析为可以轻松序列化的结构或地图,并使其足够灵活以接受不同的输入格式。

我会使用通用接口将文本转换为结构或映射,然后实现解析每个新输入类型的接口。

示例代码:(您可以运行它here

package main

import (
    "encoding/json"
    "errors"
    "fmt"
    "strings"
)

// parseFn describes the function for converting input into a map.
// This could be a struct or something else if the format is well known.
// In real code this would return map[string]interface{}, but for this
// demo I'm just using string
type parseFn func(string) (map[string]string, error)

// parseFormat1 is for fields separated by commas
func parseFormat1(in string) (map[string]string, error) {
    data := map[string]string{}
    fields := strings.Split(in, ",")
    for _, field := range fields {
        pair := strings.Split(field, "=")
        if len(pair) != 2 {
            return nil, errors.New("invalid input")
        }
        data[strings.Trim(pair[0], ` "`)] = strings.Trim(pair[1], ` "`)
    }
    return data, nil
}

// parseFormat2 is for lines with no commas
func parseFormat2(in string) (map[string]string, error) {
    data := map[string]string{}
    fields := strings.Split(in, " ")
    for _, field := range fields {
        pair := strings.Split(field, "=")
        if len(pair) != 2 {
            return nil, errors.New("invalid input")
        }
        data[strings.Trim(pair[0], ` "`)] = strings.Trim(pair[1], ` "`)
    }
    return data, nil
}

// nullFormat is what we fall back on when we just don't know
func nullFormat(in string) (map[string]string, error) { return nil, errors.New("invalid format") }

// classify just tries to guess the parser to use for the input
func classify(in string) parseFn {
    switch {
    case strings.Count(in, ", ") > 1:
        return parseFormat1
    case strings.Count(in, " ") > 1:
        return parseFormat2
    default:
        return nullFormat
    }
}

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;age="12"`,
    }

    for ix, tc := range testCases {
        pfn := classify(tc)
        d, err := pfn(tc)
        if err != nil {
            fmt.Printf("\nerror parsing on line %d: %v\n", ix, err)
            continue
        }
        b, err := json.Marshal(d)
        if err != nil {
            fmt.Printf("\nerror marshaling on line %d: %v\n", ix, err)
            continue
        }
        fmt.Printf("\nSuccess on line %d:\n INPUT: %s\nOUTPUT: %s\n", ix, tc, string(b))
    }
}