提问人:Raiane Dev 提问时间:10/6/2023 最后编辑:rob74Raiane Dev 更新时间:10/6/2023 访问量:72
解析器表 Golang
Parser Table Golang
问:
我需要找到一种使用 golang 将表转换为 JSON 的方法 有问题的表格如下所示:
State Version Support eRSTP Enhancements Bridge Priority Hello Time Max Age Time Transmit Count Forward Delay Max Hops Cost Style BPDU Guard Timeout VersionForSNMP
Disabled RSTP On 0 2 s 20 s 32 15 s 20 STP (16 bit) Don't shutdown RSTP
拆分列很简单,拆分就足够了。但请注意,值中没有分隔模式,有时是空格,有时是制表符,有时字段为空 有没有办法“解析”这个表,以便每个值都转到其相应的字段?
我希望这样的事情
[{ “State”: “已禁用”, “版本”: “RSTP”, ... }]
答:
第一个问题是它甚至不确定列标题是什么?举个例子,它可以是:禁用,:RSTP(或:RSTP和:[空]?),:开(或:开和:[空]?),:0,:2秒,:20秒,:32,:15秒,:20等。首先,你应该澄清这一点。State
Version Support
Version
Support
eRSTP Enhancements
eRSTP
Enhancements
Bridge Priority
Hello Time
Max Age Time
Transmit Count
Forward Delay
Max Hops
除此之外,我不能给你一个明确的答案,只有一些想法:
- 如果您从某人那里收到此文件,请要求他们以更可用的格式再次生成它。这实际上是唯一明智的想法,但是如果这不起作用,并且您绝对必须导入数据......
- 这张表显然是为了让列与给定的制表符大小(4?8?)对齐,也许偶尔会使用空格而不是制表符。这个想法是确定该选项卡大小,然后通过数据与标题的对齐方式进行调整。请记住,某些列可能向右对齐(尽管从示例中看起来不像)。
- 或者,您可以按照值的格式进行操作。J.F. 总是一个字符串(也许有一组有限的值?),(或?)相同,(或?)可能只是“On”或“Off”,总是数字,是数字后跟“s”等。这样,即使某些字段为空,您也可以识别该字段属于哪一列。
State
Version
Version Support
eRSTP
eRSTP Enhancements
Bridge Priority
Hello Time
- 或上述:)的某种组合
这是一个有趣的问题,我认为可以用以下算法来解决,实际上:
- 将标头和数据视为两个长度相等的字符串
- 从两个字符串的末尾迭代
- 查找所有索引,其中
headers[i - 1] == " " && headers[i] != " " && data[i - 1] == " " && data [i] != " "
找到这些索引后,我们可以使用它们来提取子字符串。
这基本上是一个尺寸为 2x2 的滑动窗口。
在第一次迭代中:
State Version Support eRSTP Enhancements Bridge Priority Hello Time Max Age Time Transmit Count Forward Delay Max Hops Cost Style BPDU Guard Timeout[ V]ersionForSNMP
Disabled RSTP On 0 2 s 20 s 32 15 s 20 STP (16 bit) Don't shutdown [ R]STP
在第二次迭代中:
State Version Support eRSTP Enhancements Bridge Priority Hello Time Max Age Time Transmit Count Forward Delay Max Hops Cost Style [ B]PDU Guard Timeout VersionForSNMP
Disabled RSTP On 0 2 s 20 s 32 15 s 20 STP (16 bit) [ D]on't shutdown RSTP
等等。 现在,让我们在 Go 中实现它:
// Input table as a single string
tableString := `State Version Support eRSTP Enhancements Bridge Priority Hello Time Max Age Time Transmit Count Forward Delay Max Hops Cost Style BPDU Guard Timeout VersionForSNMP
Disabled RSTP On 0 2 s 20 s 32 15 s 20 STP (16 bit) Don't shutdown RSTP `
// Split the table into rows based on newline characters
rows := strings.Split(tableString, "\n")
// If the header and the data rows are not the same, fail
if len(rows[0]) != len(rows[1]) {
fmt.Println("unaligned table")
return
// Other way to handle it may be to pad either the header or the data row
}
var i = len(rows[0]) - 2
var indexes []int
for i >= 0 {
if string(rows[0][i]) == " " && string(rows[0][i+1]) != " " &&
string(rows[1][i]) == " " && string(rows[1][i+1]) != " " {
indexes = append(indexes, i)
}
i--
}
我们现在拥有的都是满足我们要求的指标。 剩下的就是使用这些索引解析每一行。
var results [][]string
for _, row := range rows {
var prevIndex = 0
var parsed []string
for i := len(indexes) - 1; i >= 0; i-- {
var subs = row[prevIndex:indexes[i]]
parsed = append(parsed, subs)
prevIndex = indexes[i] + 1
}
results = append(results, parsed)
}
现在,尚不清楚您是否希望始终只有两行作为输入。但我相信从您喜欢的 JSON 输出转换为 JSON 输出应该相当容易。[][]string
正如@rob74正确提到的,我们实际上没有您的域的上下文。例如,我的代码的输出是:
[["State ","Version Support","eRSTP Enhancements","Bridge Priority","Hello Time","Max Age Time","Transmit Count","Forward Delay","Max Hops","Cost Style ","BPDU Guard Timeout"],["Disabled","RSTP ","On ","0 ","2 s ","20 s ","32 ","15 s ","20 ","STP (16 bit) ","Don't shutdown "]]
但我不知道“eRSTP Enhancements”是否是该列的正确名称,或者这是否是两列,“eRSTP”值为“On”,“Enhancements”值为“”。这是你必须解决的问题。
评论