GoLang parsing string to struct

huangapple go评论70阅读模式
英文:

GoLang parsing string to struct

问题

如何将字符串转换为结构体?

字符串的格式如下:Name[data1] Name2[data1 data2 data3] Name3[data1 data2] ...

数据可以是Int、String或Float类型。一般来说,这不重要,你可以将所有数据都写成字符串。

方括号中的数据由空格分隔。

使用正则表达式得到的结果如下:

func Parse() {
	str := "Version[2f0] Terminal[10002] Machine[10.1.1.1] DH[0.137%] Temp[45] Fan[0] Vo[4074 4042 4058 4098] CRC[0 0 0 0]"
	j := make(map[string][]string)

	re, err := regexp.Compile(`(?P<Name>[^ \[]*)\[(?P<Value>[^\]]*)`)
	if err != nil {
		log.Fatal(err)
	}
	res := re.FindAllSubmatch([]byte(str), -1)
	for _, match := range res {
		j[string(match[1])] = strings.Split(string(match[2]), " ")
	}

	log.Printf("%+v", j)
}

是否有更优雅的方法使用json.Unmarshal?

英文:

How do I convert a string to a structure?

The line looks like this: Name[data1] Name2[data1 data2 data3] Name3[data1 data2] ...

The data can be of type Int, String, or Float. In general, this is not important, you can write everything as string.

Data in brackets is separated by a space

What I got using regexp:

func Parse() {
	str := &quot;Version[2f0] Terminal[10002] Machine[10.1.1.1] DH[0.137%] Temp[45] Fan[0] Vo[4074 4042 4058 4098] CRC[0 0 0 0]&quot;
	j := make(map[string][]string)

	re, err := regexp.Compile(`(?P&lt;Name&gt;[^ \[]*)\[(?P&lt;Value&gt;[^\]]*)`)
	if err != nil {
		log.Fatal(err)
	}
	res := re.FindAllSubmatch([]byte(str), -1)
	for _, match := range res {
		j[string(match[1])] = strings.Split(string(match[2]), &quot; &quot;)
	}

	log.Printf(&quot;%+v&quot;, j)
}

Could there be a more elegant way using json.Unmarshal?

答案1

得分: 1

如果你可以使用任何你喜欢的工具,正则表达式可能会使这个问题变得相当容易。

(?P<Name>[^\[]*)\[(?P<Values>[^\]]*)\]

这个正则表达式可以匹配每个命名值集合

然后你可以使用 string.SplitValues 组中的空格分隔开。

要创建一个动态结构体,你需要使用反射。不过,在学习Go语言时要避免使用反射。Go语言中的 struct 不同于JavaScript或Python中的对象,它的字段在运行时是静态的。Go语言的 struct 用于定义静态字段。

对于这个问题,map[string][]string 可能是更合适的类型。键将是 Name 字段,值将是 data 字段。

英文:

If you're free to use any tool you like, a regular expression might make this fairly easy.

(?P&lt;Name&gt;\[^\[\]*)\[(?P&lt;Values&gt;\[^\]\]*)\]

That matches each of the named value sets.

and then you could split the Values group at the spaces with string.Split

To create a dynamic struct you'd need to use reflection. Avoid reflection, though, as you learn Go. A struct in Go is unlike an object in say Javascript or Python, where fields are dynamic at runtime. Go structs are meant to have static fields.

For this purpose, a map[string][]string would be a more appropriate type. The key would be the Name fields, and the value would be the data fields.

答案2

得分: 1

你需要为序列化数据定义一个特定的格式。其中一个关键部分是如何编码特定的特殊字符,比如 []。通常情况下,你不希望这样做。
如果你想将任何字符串作为临时文本表示你的数据,并且格式不重要,你可以使用JSON,并使用json.Marshal()json.Unmarshal()

我不确定你想要实现什么(这个结构体数据是什么?是什么生成了它?为什么你要将其解码为结构体?),但是了解一些基础知识可能会有帮助:

当你确定了你需要了解的内容时,我相信你可以通过谷歌搜索更深入的文章。

英文:
  1. You need to define a specific format for the serializing the data. A key part of that will be how to encode specific special characters, such as the [ and ]. You generally do not want to do this.
  2. If you want to use any string as a temporary textual representation of your data and the format doesn't matter, you can just use JSON and use json.Marshal() and json.Unmarshal().

I'm not sure what you are trying to achieve (what's this struct data? what generated it? why are you trying to decode it into a struct?) but it seems that going through the fundamentals might be helpful:

I'm sure you can google the more in-depth articles when you identify what you need to know for your specific purposes.

huangapple
  • 本文由 发表于 2021年12月5日 22:28:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/70235312.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定