Parsing Groovy从文本行创建映射

Parsing Groovy从文本行创建映射,parsing,dictionary,groovy,Parsing,Dictionary,Groovy,我有包含在3行中的原始数据。我想用每行的一部分构建一个地图记录。然后我阅读接下来的3行并创建下一个地图记录,依此类推。我在maps上找到的所有groovy示例都显示它们是从一行数据创建的,或者我可能误解了这些示例。下面是原始数据的样子 snmp v2: data result = "Local1" snmp v2: data result ip = "10.10.10.121" snmp v2: data result gal = "899" new snmp v2: data result =

我有包含在3行中的原始数据。我想用每行的一部分构建一个地图记录。然后我阅读接下来的3行并创建下一个地图记录,依此类推。我在maps上找到的所有groovy示例都显示它们是从一行数据创建的,或者我可能误解了这些示例。下面是原始数据的样子

snmp v2: data result = "Local1"
snmp v2: data result ip = "10.10.10.121"
snmp v2: data result gal = "899"
new
snmp v2: data result = "Local2"
snmp v2: data result ip = "192.168.10.2"
snmp v2: data result gal = "7777"
new  
我想把这些数据放到地图上。在本例中,Local1和Local2是键,它们各自有2个关联的值。我将向你们展示我的最新尝试,但这只是一个失败的猜测

def data = RAW
def map = [:]
data.splitEachLine("="){
 it.each{ x ->
 map.put(it[0], it[1])

 map.each{ k, v -> println "${k}:${v}" } }}   
所需输出为:

[ Local1 : [ ip: "10.10.10.121", gal: "899" ], 
Local2: [ ip: "192.168.10.2", gal: "7777" ] ]      

如果要按照dmahapatro的建议获得嵌套贴图,请尝试以下操作:

def map = [:]

data=data.eachLine() { line ->
  if(line.startsWith("new")) return
  tokens=line.replace("snmp v2: data","").split("=")
  tokens=tokens.collect() { it.trim().replace("result ","").replaceAll(/"/, "") }
  if(tokens[0]=="result") {
      nested=[:]
      map[tokens[1]]=nested
  }
  else
      nested[tokens[0]]=tokens[1]
}
println("map: $map")
在这里,我们:

  • 逐行迭代
  • 跳过开头带有“new”的行
  • 从行的文本中删除“snmp v2:data”
  • 将每行拆分为标记,修剪()每个标记,并删除“结果”和引号 令牌成对出现,现在看起来像:

    结果,Local1

    ip,10.10.10.121

    加尔,899

  • 接下来,当第一个标记为“result”时,我们将构建一个嵌套映射,并将其放置在主映射中由标记[1]的值给出的键处

  • 否则,我们用key=token[0]和value=token[1]填充嵌套映射
结果是:

map: [Local1:[ip:10.10.10.121, gal:899], Local2:[ip:192.168.10.2, gal:7777]]

编辑:修复了删除引号的问题

您可以使用集合上定义的聚合操作从现有数据结构构建新的数据结构;collect从现有列表生成列表,collectEntries从列表创建映射

该问题指定一个条目始终有三行,然后是一行,上面有“new”。如果我可以假设它们总是以相同的顺序排列,我可以从每一行中提取最后一个单词,使用collate将每四行分组为一个子列表,然后将每个子列表转换为一个地图条目:

lines = new File('c:/temp/testdata.txt').readLines()
mymap = lines.collect { it.tokenize()[-1] }
  .collate(4)
  .collectEntries { e-> [(e[0].replace('"', ''))) : [ip: e[1], gal: e[2]]] }
评估结果是

[Local1:[ip:"10.10.10.121", gal:"899"], Local2:[ip:"192.168.10.2", gal:"7777"]]
或删除第一步中的所有引号:

mymap = lines.collect { (it.tokenize()[-1]).replace('"', '') }
  .collate(4)
  .collectEntries { e-> [(e[0]) : [ip: e[1], gal: e[2]]] }
为了得到

[Local1:[ip:10.10.10.121, gal:899], Local2:[ip:192.168.10.2, gal:7777]]

你想让地图看起来像什么?您是否有一个您希望从上述输入中获得的输出的示例?我假设期望值是
[Local1:[ip:10.10.121],gal:899],Local2:[ip:192.168.10.2],gal:7777]
@tim_-yatest来自dmahapatro的评论是输出的外观。作为密钥的办公室名称,以及作为与密钥关联的值的ip和gal。