我从S3下载包含JSON(类似)数据的文件,我打算使用pd.read_json
将其解析为Pandas数据帧。
我的问题是转储到S3存储桶的文件使用了“八进制转义”#39;非英语字符的格式,但Python / Pandas对象包括\
字符的转义。
一个例子是字符串:"destination":"Provence-Alpes-C\\303\\264te d\'Azur"
打印为:
如果我手动删除其中一个\
个字符,那么Python会愉快地解释该字符串并将其打印为:
这个thread中有一些好东西虽然.decode('string_escape')
在单个代码段上工作得很好,但是当它包含数千条记录的更长字符串的一部分时它就不起作用了。
我认为我需要一种聪明的方法来将\\
替换为\
,但由于有充分记录的原因,.replace('\\', '\')
无法正常工作。
为了让文件完全正常工作,我使用正则表达式删除了所有\
后跟一个数字:re.sub(r'\\(?=[0-9])', '', g)
- 我认为对此进行修改可能是前进的方向,但数字需要是动态的,因为我不知道它会是什么(例如,使用\3
和\2
,上面的例子并没有开始工作' )
帮助表示赞赏。
答案 0 :(得分:1)
不是让Python解释\ooo
八进制转义,而是使用正则表达式修复JSON,然后将其解析为JSON。我之前在similar circumstances
您的数据已将UTF-8字节转义为八进制\ooo
序列,因此您需要在此处查找更有限的值范围:
import re
invalid_escape = re.compile(r'\\([1-3][0-7]{2}|[1-7][0-7]?)') # octal digits from 1 up to FF
def replace_with_codepoint(match):
return chr(int(match.group(0)[1:], 8))
def repair(brokenjson):
return invalid_escape.sub(replace_with_codepoint, brokenjson)
演示:
>>> import json
>>> sample = '{"destination":"Provence-Alpes-C\\303\\264te d\'Azur"}'
>>> repair(sample)
'{"destination":"Provence-Alpes-C\xc3\xb4te d\'Azur"}'
>>> json.loads(repair(sample))
{u'destination': u"Provence-Alpes-C\xf4te d'Azur"}
>>> print json.loads(repair(sample))['destination']
Provence-Alpes-Côte d'Azur