如何通过搜索嵌套值从 JSON 响应中提取 IPv4 地址?
How can I pull an IPv4 address from a JSON response by seacrhing nested values?
我是 Ruby 的新手,现在已经坚持了一段时间。我收到如下所述的 JSON 响应,旨在搜索其子字符串的值是我指定的值的子字符串。
例如,我收到以下响应:
{
"00:00:00:CC:00:CC": {
"family": "lladdr"
},
"10.0.0.20": {
"family": "inet",
"prefixlen": "24",
"netmask": "255.255.255.0",
"broadcast": "10.0.0.255",
"scope": "Global"
},
"ff00::f00:00ff:fff0:00f0": {
"family": "inet6",
"prefixlen": "64",
"scope": "Link",
"tags": []
}
}
我需要获取键 family
的值等于 inet
的父项的值。在这种情况下,当 family 等于 inet.
时,我只想将 10.0.0.20
作为输出
我在这里经历了多个问题,Google 没有帮助。我知道我需要使用 JSON.parse
解析 JSON,然后使用 maybe find 或 select 来得到我的答案,但我无法让它工作。
我不确定是否有任何其他方法可以做到这一点,就像您在 Bash 中使用 grep 或 awk 所做的那样。一种 hack 可能是使用 foo.[46..54]
之类的东西来输出 IP,但我再次认为这不是解决这个问题的好方法。
如果你想要 family
inet
,
result = JSON.parse(response)
family = result.detect { |k,v| v['family'] == 'inet' }
family[0] # 10.0.0.20
请注意,检测将 return 一个数组。
使用哈希#invert
假设您的哈希已经使用 JSON#parse, one way to solve the problem is to invert the Hash with the Hash#invert 方法存储在 response 中。例如:
# Return an Array of IPv4, then pop the last/only String value.
response.invert.select { |h| h.values.include? 'inet' }.values.pop
#=> "10.0.0.20"
这既快速又简单,并且适用于您提供的数据。但是,有一些小警告。
注意事项
假设 response 哈希中只有一个 IPv4 地址。如果您有多个以 inet
作为值的键,请不要使用 pop
并按您认为合适的方式处理结果数组。例如:
response.invert.select { |h| h.values.include? 'inet' }.values
#=> ["10.0.0.20"]
它假定每个顶级 JSON 对象的键是一个 IP 地址。我们并没有真正验证任何东西。
它适用于您拥有的 JSON,但不能解决任意嵌套或变化的数据结构。如果您有不同类型的输入,请考虑 "some assembly required."
如果你没有inet
家庭,那么{}.values.pop
可能return没有。请确保您在申请中对此进行了规划。
None 这些是您特定用例的阻碍因素,但它们确实值得牢记。您的里程可能会有所不同。
我是 Ruby 的新手,现在已经坚持了一段时间。我收到如下所述的 JSON 响应,旨在搜索其子字符串的值是我指定的值的子字符串。
例如,我收到以下响应:
{
"00:00:00:CC:00:CC": {
"family": "lladdr"
},
"10.0.0.20": {
"family": "inet",
"prefixlen": "24",
"netmask": "255.255.255.0",
"broadcast": "10.0.0.255",
"scope": "Global"
},
"ff00::f00:00ff:fff0:00f0": {
"family": "inet6",
"prefixlen": "64",
"scope": "Link",
"tags": []
}
}
我需要获取键 family
的值等于 inet
的父项的值。在这种情况下,当 family 等于 inet.
10.0.0.20
作为输出
我在这里经历了多个问题,Google 没有帮助。我知道我需要使用 JSON.parse
解析 JSON,然后使用 maybe find 或 select 来得到我的答案,但我无法让它工作。
我不确定是否有任何其他方法可以做到这一点,就像您在 Bash 中使用 grep 或 awk 所做的那样。一种 hack 可能是使用 foo.[46..54]
之类的东西来输出 IP,但我再次认为这不是解决这个问题的好方法。
如果你想要 family
inet
,
result = JSON.parse(response)
family = result.detect { |k,v| v['family'] == 'inet' }
family[0] # 10.0.0.20
请注意,检测将 return 一个数组。
使用哈希#invert
假设您的哈希已经使用 JSON#parse, one way to solve the problem is to invert the Hash with the Hash#invert 方法存储在 response 中。例如:
# Return an Array of IPv4, then pop the last/only String value.
response.invert.select { |h| h.values.include? 'inet' }.values.pop
#=> "10.0.0.20"
这既快速又简单,并且适用于您提供的数据。但是,有一些小警告。
注意事项
假设 response 哈希中只有一个 IPv4 地址。如果您有多个以
inet
作为值的键,请不要使用pop
并按您认为合适的方式处理结果数组。例如:response.invert.select { |h| h.values.include? 'inet' }.values #=> ["10.0.0.20"]
它假定每个顶级 JSON 对象的键是一个 IP 地址。我们并没有真正验证任何东西。
它适用于您拥有的 JSON,但不能解决任意嵌套或变化的数据结构。如果您有不同类型的输入,请考虑 "some assembly required."
如果你没有
inet
家庭,那么{}.values.pop
可能return没有。请确保您在申请中对此进行了规划。
None 这些是您特定用例的阻碍因素,但它们确实值得牢记。您的里程可能会有所不同。