解析表Golang

ogq8wdun  于 2023-10-14  发布在  Go
关注(0)|答案(2)|浏览(124)

我需要找到一种方法用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

拆分列很简单,拆分就足够了。但是请注意,在值中没有分隔模式,有时它是一个空格,有时是一个制表符,有时字段是空的。是否有任何方法可以“解析”这个表,以便每个值都进入相应的字段?
我希望这样的事情
[{“状态”:“已禁用”,“版本”:“RSTP”,.}]

bihw5rsg

bihw5rsg1#

第一个问题是,它甚至不确定列标题是什么?例如,它可以是State:禁用,Version Support:RSTP(或Version:RSTP和Support:[空]?),eRSTP Enhancements:打开(或eRSTP:关于Enhancements:[空]?),Bridge Priority:0,Hello Time:2秒,Max Age Time:20秒,Transmit Count:32,Forward Delay:15秒,Max Hops:第20章首先,你要澄清
除此之外,我无法给予你一个明确的答案,只能给出一些想法:

  • 如果你从某人那里收到了这个文件,请他们以更有用的格式重新生成它。这实际上是唯一明智的想法,但如果这不起作用,你绝对 * 必须 * 导入数据。
  • 这个表显然是这样构建的,列与给定的选项卡大小对齐(4?8?),也许偶尔使用空格而不是制表符。这个想法是确定标签大小,然后通过数据与标题的对齐来进行。请记住,有些列可能会向右对齐(尽管在示例中看起来不像这样)。
  • 或者你也可以通过数值的格式来判断。也就是说,State始终是一个字符串(可能有一组有限的值)。)、Version(或Version Support?)相同,eRSTP(或eRSTP Enhancements?)可能只是“On”或“Off”,Bridge Priority总是数字,Hello Time是数字后跟“s”等。这样,即使某些字段为空,您也可以确定字段属于哪一列。
  • 或者以上的一些组合:)
yqlxgs2m

yqlxgs2m2#

这是一个有趣的问题,我认为它可以用下面的算法来解决:
1.将头和数据看作两个长度相等的字符串
1.从两个字符串的末尾开始迭代
1.查找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)
}

现在,还不清楚您是否希望始终只有两行作为输入。但我相信从[][]string转换到您喜欢的JSON输出应该相当容易。
正如@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”值为“"。这是你必须解决的问题

相关问题