解析器表 Golang

Parser Table Golang

提问人:Raiane Dev 提问时间:10/6/2023 最后编辑:rob74Raiane Dev 更新时间:10/6/2023 访问量:72

问:

我需要找到一种使用 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”, ... }]

JSON Go 解析

评论

0赞 Burak Serdar 10/6/2023
必须有一些分隔符来分隔数据值,可能是制表符或固定宽度值,否则这在任何语言中都是不可解析的。

答:

0赞 rob74 10/6/2023 #1

第一个问题是它甚至不确定列标题是什么?举个例子,它可以是:禁用,:RSTP(或:RSTP和:[空]?),:开(或:开和:[空]?),:0,:2秒,:20秒,:32,:15秒,:20等。首先,你应该澄清这一点。StateVersion SupportVersionSupporteRSTP EnhancementseRSTPEnhancementsBridge PriorityHello TimeMax Age TimeTransmit CountForward DelayMax Hops

除此之外,我不能给你一个明确的答案,只有一些想法:

  • 如果您从某人那里收到此文件,请要求他们以更可用的格式再次生成它。这实际上是唯一明智的想法,但是如果这不起作用,并且您绝对必须导入数据......
  • 这张表显然是为了让列与给定的制表符大小(4?8?)对齐,也许偶尔会使用空格而不是制表符。这个想法是确定该选项卡大小,然后通过数据与标题的对齐方式进行调整。请记住,某些列可能向右对齐(尽管从示例中看起来不像)。
  • 或者,您可以按照值的格式进行操作。J.F. 总是一个字符串(也许有一组有限的值?),(或?)相同,(或?)可能只是“On”或“Off”,总是数字,是数字后跟“s”等。这样,即使某些字段为空,您也可以识别该字段属于哪一列。StateVersionVersion SupporteRSTPeRSTP EnhancementsBridge PriorityHello Time
  • 或上述:)的某种组合
0赞 Alexey Soshin 10/6/2023 #2

这是一个有趣的问题,我认为可以用以下算法来解决,实际上:

  1. 将标头和数据视为两个长度相等的字符串
  2. 从两个字符串的末尾迭代
  3. 查找所有索引,其中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”值为“”。这是你必须解决的问题。