使用json.loads,key不带引号,且value中可能含有“:”,如何最好地处理?

例如:

'''{
    colorSize: [{
        "Color": "超窄边IPS",
        "SkuId": 1365289,
        "Size": "27英寸"
    }, {
        "Color": "21:9超宽IPS曲面",
        "SkuId": 1742140,
        "Size": "29英寸"
    }, {
        "Color": "17英寸(TN,5:4方屏)",
        "SkuId": 1032147,
        "Size": "17英寸"
    }],
    warestatus: 1,
    shangjiazizhi: false
}'''

为了给key加双引号,必需先选中之
因为内容带有“:”,

  1. (\w+):,误处理"21:9超宽IPS曲面"

  2. [{,]\s*(\w+):,误处理"17英寸(TN,5:4方屏)"

有什么比较好的处理方法呢?

阅读 16k
5 个回答

手机版不能看到完整标题,能回复一下吗
手机版还不能回复评论,恼火
更新一下,前面匹配一个空格

\s([^"]+):

或者前面匹配一个行首

^([^"]+):

两种方案
一种像@raidou说的使用demjson
一种使用pyexecjs
上代码

import execjs
import demjson

str = '''
{
    colorSize: [{
        "Color": "超窄边IPS",
        "SkuId": 1365289,
        "Size": "27英寸"
    }, {
        "Color": "21:9超宽IPS曲面",
        "SkuId": 1742140,
        "Size": "29英寸"
    }, {
        "Color": "17英寸(TN,5:4方屏)",
        "SkuId": 1032147,
        "Size": "17英寸"
    }],
    warestatus: 1,
    shangjiazizhi: false
}
'''
print demjson.decode(str)
print execjs.eval(str)

试用了下其他答案提到的demjson,解析速度实在是难以接受,于是自己用正则处理了一下,写了个函数。

def quote_keys_for_json(json_str):
    """给键值不带双引号的json字符串的所有键值加上双引号。
    注:解析一般的不严格的json串,也可以用demjson库, 速度比较慢。"""
    #把原字符串的双引号对用@替换
    quote_pat = re.compile(r'"[^"]*"')
    a = quote_pat.findall(json_str)
    json_str = quote_pat.sub('@', json_str)
    #给键值加上双引号
    key_pat = re.compile(r'(\w+):')
    json_str = key_pat.sub(r'"\1":', json_str)
    #把@换成原来的双引号对
    assert json_str.count('@') == len(a)
    count = -1
    def put_back_values(match):
        nonlocal count
        count += 1
        return a[count]
    json_str = re.sub('@', put_back_values, json_str)
    return json_str

函数可以直接使用,唯一限制是双引号必须成对出现。如果有其他要求可以自己修改代码。

自己解决了,简单说一下:
最关键是这些丧心病狂的:号必然出现在成对的"

因为双引号总是成对出现且不交叉
用 re.sub 把成对的双引号过滤,然后滤出结果交给函数处理:将双引号中间的冒号替换成特殊字符,为了描述方便我把这个字符称为

再用之前带冒号的正则处理替换后不带内容冒号的结果

那么新问题来了,key加好双引号之后,假如我要把 替换回:,那么 选择什么特殊字符最妥呢?

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
1 篇内容引用
推荐问题