Python处理非标准Json的一些坑和解决方案

Python的json模块只能处理标准的json格式,任何不标准的json的格式丢进json.loads()都会立即报错:

以下是一段供测试的非标准json字符串:

a = {'MsgId':'61226578','FromUserName':'@2b55d8116fdc604e8a531c952676907','ToUserName':'@2b55d8116fdc604e8a531c952676907','MsgType':1,'Content':'你好,世界','Status':3,'ImgStatus':1,'CreateTime':1674026102,'VoiceLength':0,'PlayLength':0,'FileName':'','FileSize':'','MediaId':'','Url':'','AppMsgType':0,'StatusNotifyCode':0,'StatusNotifyUserName':'','RecommendInfo':{'UserName':'','NickName':'','QQNum':0,'Province':'','City':'','Content':'','Signature':'','Alias':'','Scene':0,'VerifyFlag':0,'AttrStatus':0,'Sex':0,'Ticket':'','OpCode':0},'ForwardFlag':0,'AppInfo':{'AppID':'','Type':0},'HasProductId':0,'Ticket':'','ImgHeight':0,'ImgWidth':0,'SubMsgType':0,'NewMsgId':6231932783261226578,'OriContent':'','EncryFileName':'','User':<User:{'MemberList':<ContactList:[]>,'Uin':0,'UserName':'@2b55d8116fdc604e8a531c952676907','NickName':'LegendNoTitle','HeadImgUrl':'/cgi-bin/mmwebwx-bin/webwxgeticon?seq=20230118&username=@2b55d8116fdc604e8a531c952676907&skey=@crypt_2edbde23b_1f20242edbde23bfddaeb33c23ed0aca','ContactFlag':3,'MemberCount':0,'RemarkName':'LegendNoTitle','HideInputBarFlag':0,'Sex':1,'Signature':'你好,世界','VerifyFlag':0,'OwnerUin':0,'PYInitial':'LegendNoTitle','PYQuanPin':'LegendNoTitle','RemarkPYInitial':'LegendNoTitle','RemarkPYQuanPin':'LegendNoTitle','StarFriend':0,'AppAccountFlag':0,'Statues':0,'AttrStatus':16912677,'Province':'其他','City':'其他','Alias':'','SnsFlag':1,'UniFriend':0,'DisplayName':'','ChatRoomId':0,'KeyWord':'','EncryChatRoomId':'','IsOwner':0,'HeadImgUpdateFlag':1,'ContactType':0,'ChatRoomOwner':''}>,'Type':'Text','Text':'你好,世界'}

会报json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1) 的错误,也就是不能用单引号,必须用双引号。

那如果把单引号全部改成双引号呢?

b =str.replace(' ','').replace('\n','').replace('\r','').replace("'",'"')
print(json.loads(b))

依然是报错:json.decoder.JSONDecodeError: Expecting value: line 1 column 799 (char 798)

放到json校验工具里面看看究竟:

在”User”里面插了一个XML,导致json模块报错,这个问题我搜了好久都没有看到合适的解决方案,还好我需要的数据不在User里,直接去掉也没事吧。

直接上正则表达式结合re模块:

c = re.sub('<.*>', '', b) #贪婪模式匹配'<'和'>'间的所有字符,并替换为空

依旧报错啊……而且报错的内容还是Expecting value:

丢到Json校验工具里面看看究竟:

看到了一个相当可疑的地方:我们将User下的XML删除后,User下没有任何值了。

可能刚刚替换的时候,应该把XML换成一对双引号。

c = re.sub('<.*>', '""', b) #贪婪模式匹配'<'和'>'间的所有字符,并替换为双引号

完美。


另外,如果你的json字符串中没有我刚刚的那种XML,可以不进行单引号转双引号的替换。直接使用一个第三方库demjson解决。

demjson就是为了解决json模块严格而导致转换失败而生的。

pip install demjson

以刚刚的示例字符串为例,

import demjson
# 这里有 a = {'xxx':xxx,'xxxx':xxxx} 详情见上。
b = re.sub('<.*>', '""', a) #匹配'<'和'>'间的所有字符,并替换为双引号,因为demjson无法解决上述的Json套XML的问题
print(demjson.decode(b))

看到一篇博文说Json内套XML是原生支持的……不清楚具体是什么情况了,如果能原生支持内套XML,那我应该也不用正则去掉XML区块了,直接一个替换或者demjson搞定多快乐

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值