如何从 python 中嵌套的 json 中的键替换字符

how to replace character from keys in a nested json in python

"127.0.0.1": {
        "nmaprun": {
            "@scanner": "nmap",
            "@args": "nmap -v -sS -sV -sC -A -O -oX nmap 127.0.0.1 1-1024",
            "@start": "1645467733",
            "@startstr": "Mon Feb 21 23:52:13 2022",
            "@version": "7.91",
            "@xmloutputversion": "1.05",
            "scaninfo": {
                "@type": "syn",
                "@protocol": "tcp",
                "@numservices": "1000",
                "@services": "1,3-4,6-7,9,13,17,19-26,
            },
            "verbose": {
                "@level": "1"
            },
            "debugging": {
                "@level": "0"
            },
        
            "runstats": {
                "finished": {
                    "@time": "1645467744",
                    "@timestr": "Mon Feb 21 23:52:24 2022",
                    "@summary": "Nmap done at Mon Feb 21 23:52:24 2022; 1 IP address (1 host up) scanned in 12.14 seconds",
                    "@elapsed": "12.14",
                    "@exit": "success"
                }
            }
        }
    }
}

我有 Nmap 的扫描输出。我想解析整个 JSON 并将 '@' 字符替换为 ''。 我如何在 python 中执行此操作?

一种可能的方法是迭代键,然后弹出给定键的项目并将其分配给不带@的键,如果键以@开头,因为你有嵌套结构,你需要递归地遍历这些键

def recursive_replace(data):
    for key in data.keys():
        if key.startswith('@'):
            data[key[1:]] = data.pop(key)
            key = key[1:]
        if isinstance(data[key], dict):
            data[key]=recursive_replace(data[key])
    return data

输出:

>>> #assuming data holds the dictionary
>>> recursive_replace(data)
{
  "127.0.0.1": {
    "nmaprun": {
      "scaninfo": {
        "type": "syn",
        "protocol": "tcp",
        "numservices": "1000",
        "services": "1,3-4,6-7,9,13,17,19-26,"
      },
      "verbose": {
        "level": "1"
      },
      "debugging": {
        "level": "0"
      },
      "runstats": {
        "finished": {
          "time": "1645467744",
          "summary": "Nmap done at Mon Feb 21 23:52:24 2022; 1 IP address (1 host up) scanned in 12.14 seconds",
          "elapsed": "12.14",
          "exit": "success",
          "timestr": "Mon Feb 21 23:52:24 2022"
        }
      },
      "scanner": "nmap",
      "start": "1645467733",
      "startstr": "Mon Feb 21 23:52:13 2022",
      "version": "7.91",
      "xmloutputversion": "1.05",
      "args": "nmap -v -sS -sV -sC -A -O -oX nmap 127.0.0.1 1-1024"
    }
  }
}
dic = {"127.0.0.1": {
    "nmaprun": {
        "@scanner": "nmap",
        "@args": "nmap -v -sS -sV -sC -A -O -oX nmap 127.0.0.1 1-1024",
        "@start": "1645467733",
        "@startstr": "Mon Feb 21 23:52:13 2022",
        "@version": "7.91",
        "@xmloutputversion": "1.05",
        "scaninfo": {
            "@type": "syn",
            "@protocol": "tcp",
            "@numservices": "1000",
            "@services": "1,3-4,6-7,9,13,17,19-26",
        },
        "verbose": {
            "@level": "1"
        },
        "debugging": {
            "@level": "0"
        },

        "runstats": {
            "finished": {
                "@time": "1645467744",
                "@timestr": "Mon Feb 21 23:52:24 2022",
                "@summary": "Nmap done at Mon Feb 21 23:52:24 2022; 1 IP address (1 host up) scanned in 12.14 seconds",
                "@elapsed": "12.14",
                "@exit": "success"
            }
        }
    }
}}
def remove_at(d):
    if isinstance(d, dict):
        return {k.lstrip('@'): remove_at(v) for k, v in d.items()}
    elif isinstance(d, list):
        return [remove_at(v) for v in d]
    else:
        return d

print(remove_at(dic))