我需要将代表字典的python字符串转换为python字典。该字符串可能包含任何有效的dict表示形式,包括Windows样式路径(带有反斜杠),例如
mystring = u'{"baselocaldir":"c:\\tmp\\SrcTmp\\RepManager"}'
我需要一个通用的str来进行dict转换函数,因此这只是源字符串的一个示例,无法正常工作。源字符串可能来自外部源。首选与python 2/3兼容的解决方案。
我已经尝试了给出的答案:
json.loads不起作用(即使我将字符串重新格式化为json语法):引发异常
ast.literal_eval不起作用:在此示例中,它在结果中放置了制表符
eval:与ast.literal_eval相同的结果
答案 0 :(得分:1)
我会对字符串进行黑客攻击,以将'c:'替换为原始字符串文字r'c:'
mystring = u'{"baselocaldir": "c:\\tmp\\SrcTmp\\RepManager"}'.replace('"c:', 'r"c:')
_dict = eval(mystring)
_dict
结果:
{'baselocaldir': 'c:\\tmp\\SrcTmp\\RepManager'}
答案 1 :(得分:1)
Edit3:在op中将示例字符串更改为双反斜杠后,它变得更容易,并且无需使用正则表达式:
mystring = u'{"baselocaldir":"c:\\tmp\\SrcTmp\\RepManager"}'
test = repr(mystring)[1:-1]
print(test)
# convert to dictionary
my_dict = json.loads(test)
print('dict key "baselocaldir" = ', my_dict["baselocaldir"])
输出:
{"baselocaldir":"c:\\tmp\\SrcTmp\\RepManager"}
dict key "baselocaldir" = c:\tmp\SrcTmp\RepManager
Edit2:显然仅使用repr()是不够的,这就是为什么我编辑答案以使用正则表达式并将所有\
替换为\\
的原因,这是代码:
import re, json
mystring = u'{"baselocaldir":"c:\tmp\SrcTmp\RepManager"}'
test = re.sub(r'(?<=[^\\])\\(?=[^\\])', r'\\\\', repr(mystring)[1:-1])
print(test)
# convert to dictionary
my_dict = json.loads(test)
print('dict key "baselocaldir" = ', my_dict["baselocaldir"])
输出:
{"baselocaldir":"c:\\tmp\\SrcTmp\\RepManager"}
dict key "baselocaldir" = c:\tmp\SrcTmp\RepManager
先前的答案,这是不够的
编辑:
将字符串转换为原始格式的简单方法是使用repr()
或"%r"
这是一个一步的解决方案,功劳归功于Nishanth Amuluru and Jed Alexander 9年前:
mystring = u'{"baselocaldir":"c:\tmp\SrcTmp\RepManager"}'
raw_str = "%r"%mystring
rep_str= repr(mystring)
print('original string = ', mystring)
print('Raw string = ', raw_str)
print('rep string = ', rep_str)
输出:
original string = {"baselocaldir":"c: mp\SrcTmp\RepManager"}
Raw string = '{"baselocaldir":"c:\tmp\\SrcTmp\\RepManager"}'
rep string = '{"baselocaldir":"c:\tmp\\SrcTmp\\RepManager"}'
答案 2 :(得分:0)
我的(也许不是最优雅的)解决方案:
但是它适用于python2,python3以及unicode字符串中的unichar字符:
text_type = None
if PY2:
string_types = basestring
text_type = unicode
else:
string_types = text_type = str
def DictUnescaceBackslash(oDict):
for key, value in iteritems(oDict):
if isinstance(value, dict):
DictUnescaceBackslash(value)
elif isinstance(value, string_types):
oDict[key]=oDict[key].replace("***BaCkSlAsH***","\\")
elif isinstance(value, list):
for elem in value:
DictUnescaceBackslash(elem)
mystring = u'{"baselocaldir":"c:\\tmp\\SrcTmp\\RepManager"}'
uString2 = mystring.replace("\\","***BaCkSlAsH***")
dDict = ast.literal_eval(uString2)
DictUnescaceBackslash(dDict)