多行JSON的Python正则表达式

时间:2019-09-04 13:17:26

标签: python regex

由于某些无法控制的原因,我正在处理需要与Regexp解析的JSON文档。

我有以下文件:

{
  "overall_status_ok" : true,
  "reply_host" : "ip-10-182-81-74.eu-west-1.compute.internal",
  "cached_ts" : "2019-09-02T14:44:53+0000",
  "status" : "UP",
  "ssh" : {
    "status_ok" : true
  }
}

我想出了以下几点来获取SSH的状态:

(\"overall_status_ok\".*true,)
(.*(.*\n).*)+
(\"ssh\".*(.*\n).*\"status_ok\"[\ :]+true)

但是,此操作不起作用,导致检测到灾难性的回溯,并且您在https://regex101.com/上停止执行表达式

我需要检查total_status_ok为true和ssh status_ok为true。我只在寻找正则表达式,而不是Python代码。

不确定是什么问题。

3 个答案:

答案 0 :(得分:1)

我想不出您为什么要这样做的原因 (请在生产中不要这样做),但是如果要使用regex,则可以使用regex捕获所有真实的* status_ok条目,并检查是否包括了所需的条目。

工作示例(使用Python 3.7):

import re

txt = """
{
  "overall_status_ok" : true,
  "reply_host" : "ip-10-182-81-74.eu-west-1.compute.internal",
  "cached_ts" : "2019-09-02T14:44:53+0000",
  "status" : "UP",
  "ssh" : {
    "status_ok" : true
  }
}"""

if set(m.group(1) 
       for m in re.finditer('\"(.*status_ok)\"\s*:\s*true', txt)
        ).issuperset({'overall_status_ok', 'status_ok'}):
    print('both are true')

更新:

一行正则表达式(使用上面的 txt )将像这样工作:

re.search('(?s)\"(overall_status_ok)\"\s*:\s*true.*?ssh.*\"(status_ok)\"\s*:\s*true', txt)

答案 1 :(得分:1)

从想象中看这还不是很漂亮,但这可能会起作用:

    let index = arrayFromObject(servers).reduce(
      (index, { ServerName, ...server }) => ({ ...index, [ServerName]: server }), {});

https://regex101.com/r/rfyNnS/2

答案 2 :(得分:1)

实际上,您应该始终使用JSON解析器来解析JSON数据。

作为一些解决方法,您可以尝试修复正则表达式以摆脱会导致灾难性回溯的(.*(.*\n).*)+部分,因为此模式会产生太多与字符串匹配的可能性:

(?s)(\"overall_status_ok\"[\s:]+true,)\s*(.*?)\s*(\"ssh\".*?\"status_ok\"[\s:]+true)

请参见regex demo

详细信息

  • (?s)-re.DOTALL修饰符内联版本
  • (\"overall_status_ok\"[\s:]+true,)-第1组:"overall_status_ok"字符串,1个以上的空格和冒号,然后是true,子字符串
  • \s*-超过0个空格
  • (.*?)-第2组:0个以上的字符,但尽可能少
  • \s*-超过0个空格
  • (\"ssh\".*?\"status_ok\"[\s:]+true)-第3组:"ssh",然后是任意0+个字符,但应尽可能少,然后是"status_ok",1+个空格和冒号,然后是true,子字符串