在python中的Unescape json字符串

时间:2017-08-21 12:38:40

标签: json python-2.7

我从日志文件中获取以下字符串,我想从字符串中删除反斜杠。

文件中的字符串:

这是日志文件的确切字符串,除了用虚拟值替换的一些敏感信息。

2017-08-17 17:29:49.249  ERROR org.foo.bar.logging.ApplicationLogger - APIError={"input":"{\"requestBody\":\"{\\\"request\\\":{\\\"drequests\\\":{\\\"items\\\":[{\\\"Description\\\":\\\"I would like to add an additional card.\\\",\\\"Fields\\\":{\\\"Field\\\":[{\\\"FieldName\\\":\\\"Severity\\\",\\\"FieldValue\\\":\\\"4\\\"},{\\\"FieldName\\\":\\\"Contact\\\",\\\"FieldValue\\\":\\\"Phone\\\"},{\\\"FieldName\\\":\\\"CallbackNumber\\\",\\\"FieldValue\\\":\\\"1 (123) 123456\\\"},{\\\"FieldName\\\":\\\"Version\\\",\\\"FieldValue\\\":\\\"11.1\\\"},{\\\"FieldName\\\":\\\"Language\\\",\\\"FieldValue\\\":\\\"English\\\"}]},\\\"Product\\\":\\\"Visa\\\",\\\"Subject\\\":\\\"Adding an addition card\\\",\\\"Serial_Number\\\":\\\"123456789\\\"}]},\\\"Email\\\":\\\"someone@gmail.com\\\",\\\"First_Name\\\":\\\"Foo\\\",\\\"Last_Name\\\":\\\"Bar\\\"}}\"}"}

Python代码

str = read_from_file()
print str.replace('\\"', '"')

我尝试了这行代码,但没有任何效果。如何从json字符串中删除backslahses?

修改

我尝试了递归执行json.loads的解决方案,但没有删除反斜杠。

只是为了给出更好的上下文 - 我不是将这个json字符串作为JSON处理,而是将其写入另一个文件,因此它对另一个人更具可读性。以下是我的完整代码。

import re
import json
from tailf import tailf


def parseRecursive(obj):
    if isinstance(obj, str):
        try:  # see whether it is JSON: if so, parse it
            obj = json.loads(obj)
        except json.JSONDecodeError:
            pass  # if not, leave it like it is
        if isinstance(obj, dict):  # perform recursion
            for prop, val in obj.items():
                obj[prop] = parseRecursive(val)
    return obj


for line in tailf("/var/log/test.log"):
    m = re.search('([\d\-:\s]+).*ERROR.*APIError=(.*)', line)
    if m is None:
        print "No match"
    else:
        print m.group(1)
        print parseRecursive(m.group(2));

当我运行此脚本时,它将打印字符串并且根本不删除反斜杠,同时注意第二行开头的两个u'字符。

输出

2017-08-17 17:29:49
{u'input': u'{"requestBody":"{\\"request\\":{\\"drequests\\":{\\"items\\":[{\\"Description\\":\\"I would like to add an additional card.\\",\\"Fields\\":{\\"Field\\":[{\\"FieldName\\":\\"Severity\\",\\"FieldValue\\":\\"4\\"},{\\"FieldName\\":\\"Contact\\",\\"FieldValue\\":\\"Phone\\"},{\\"FieldName\\":\\"CallbackNumber\\",\\"FieldValue\\":\\"1 (123) 123456\\"},{\\"FieldName\\":\\"Version\\",\\"FieldValue\\":\\"11.1\\"},{\\"FieldName\\":\\"Language\\",\\"FieldValue\\":\\"English\\"}]},\\"Product\\":\\"Visa\\",\\"Subject\\":\\"Adding an addition card\\",\\"Serial_Number\\":\\"123456789\\"}]},\\"Email\\":\\"someone@gmail.com\\",\\"First_Name\\":\\"Foo\\",\\"Last_Name\\":\\"Bar\\"}}"}'}

更新

这是一个愚蠢的错误!我必须将oobject键入case,然后调用replace函数。以下代码有效。

import re
from tailf import tailf

for line in tailf("/var/log/test.log"):
    m = re.search('([\d\-:\s]+).*ERROR.*APIError=(.*)', line)
    if m is None:
        print "No match"
    else:
        print m.group(1)
        encodedString = m.group(2) + ''
        print str(encodedString).replace('\\', '')

1 个答案:

答案 0 :(得分:0)

字符串中表示的JSON需要反斜杠,因为显然表示的对象具有本身是JSON编码字符串的属性值。这些嵌入的字符串需要对其双引号进行转义。删除它们会使整体JSON无效。

您可能需要将嵌入的JSON字符串解析为它们所代表的对象。为此,您最好使用递归函数,该函数使用json.loads方法来解析每个嵌套的JSON。

注意:对您的数据使用名称str不是一个好主意,因为这是Python数据类型的名称。

这是建议的解决方案:

import json
import re

def parseRecursive(obj):
    if isinstance(obj, basestring):
        try: # see whether it is JSON: if so, parse it
            obj = json.loads(obj)
        except json.JSONDecodeError:
            pass # if not, leave it like it is
        if isinstance(obj, dict): # perform recursion
            for prop, val in obj.items():
                obj[prop] = parseRecursive(val)
    return obj

# Sample Input
msg = r'2017-08-17 17:29:49.249  ERROR org.foo.bar.logging.ApplicationLogger - APIError={"input":"{\"requestBody\":\"{\\\"request\\\":{\\\"drequests\\\":{\\\"items\\\":[{\\\"Description\\\":\\\"I would like to add an additional card.\\\",\\\"Fields\\\":{\\\"Field\\\":[{\\\"FieldName\\\":\\\"Severity\\\",\\\"FieldValue\\\":\\\"4\\\"},{\\\"FieldName\\\":\\\"Contact\\\",\\\"FieldValue\\\":\\\"Phone\\\"},{\\\"FieldName\\\":\\\"CallbackNumber\\\",\\\"FieldValue\\\":\\\"1 (123) 123456\\\"},{\\\"FieldName\\\":\\\"Version\\\",\\\"FieldValue\\\":\\\"11.1\\\"},{\\\"FieldName\\\":\\\"Language\\\",\\\"FieldValue\\\":\\\"English\\\"}]},\\\"Product\\\":\\\"Visa\\\",\\\"Subject\\\":\\\"Adding an addition card\\\",\\\"Serial_Number\\\":\\\"123456789\\\"}]},\\\"Email\\\":\\\"someone@gmail.com\\\",\\\"First_Name\\\":\\\"Foo\\\",\\\"Last_Name\\\":\\\"Bar\\\"}}\"}"}'

# Extract json part: take "{ ... }" from message string
match = re.search(r"\{.*\}", msg)
if match:
    # parse nested JSON
    obj = parseRecursive(match.group(0))
    print obj

看到它在repl.int上运行。请注意,输出objdict。输出中带前缀的u表示键是unicode字符串。但您可以访问其中的任何嵌套值,例如:

print obj['input']['requestBody']['request']['Email']

输出:

  

someone@gmail.com