简体   繁体   English

将包含转义字符的字符串转换为字典

[英]Convert string which contains escape characters to a dict

I need to convert a python string which represents a dict into a python dict.我需要将表示 dict 的 python 字符串转换为 python dict。 The string might contain any valid dict representation, including windows style pathes (with backslashes), eg该字符串可能包含任何有效的 dict 表示,包括 Windows 样式路径(带反斜杠),例如

mystring = u'{"baselocaldir":"c:\\tmp\\SrcTmp\\RepManager"}'

I would need a generic str to dict convert function, so this is just an example of a source string, which doesn't work.我需要一个通用的 str 来 dict 转换函数,所以这只是一个源字符串的例子,它不起作用。 The source string might come from external sources.源字符串可能来自外部源。 A python 2/3 compatible solution would be preferred.首选 python 2/3 兼容解决方案。

I already tried the given answers:我已经尝试过给出的答案:

json.loads does not work (even if I reformat the string to json syntax): raises exception json.loads 不起作用(即使我将字符串重新格式化为 json 语法):引发异常

ast.literal_eval does not work: in this example it places a tab character in the result ast.literal_eval 不起作用:在这个例子中它在结果中放置了一个制表符

eval: the same result as ast.literal_eval eval:与 ast.literal_eval 结果相同

I would put a hack on the string to replace 'c:' as a raw string literal r'c:'我会对字符串进行修改以将 'c:' 替换为原始字符串文字 r'c:'

mystring = u'{"baselocaldir": "c:\\tmp\\SrcTmp\\RepManager"}'.replace('"c:', 'r"c:') 
_dict = eval(mystring)
_dict

Result:结果:

{'baselocaldir': 'c:\\tmp\\SrcTmp\\RepManager'}

Edit3: after op change the sample string to double backslash, it is easier and no need to use regex: 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"])

output:输出:

{"baselocaldir":"c:\\tmp\\SrcTmp\\RepManager"}
dict key "baselocaldir" =  c:\tmp\SrcTmp\RepManager

Edit2: apparently using repr() alone is not enough, that's why i edited my answer to use regex and replace all the \\ to \\\\ , here is the code: 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"])

output:输出:

{"baselocaldir":"c:\\tmp\\SrcTmp\\RepManager"}
dict key "baselocaldir" =  c:\tmp\SrcTmp\RepManager

previous answer, which is not enough Edit: simple way to convert a string to raw is to use repr() or "%r"以前的答案,这还不够 编辑:将字符串转换为原始字符串的简单方法是使用repr()"%r"

Here is a one step solution, credits goes to Nishanth Amuluru and Jed Alexander 9 years ago:这是一个一步解决方案,归功于Nishanth Amuluru 和 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)

output:输出:

original string =  {"baselocaldir":"c:  mp\SrcTmp\RepManager"}
Raw string =  '{"baselocaldir":"c:\tmp\\SrcTmp\\RepManager"}'
rep string =  '{"baselocaldir":"c:\tmp\\SrcTmp\\RepManager"}'

My (maybe not most elegant) solution:我的(也许不是最优雅的)解决方案:

But it works on python2 , python3 and with unicode chars in unicode strings:但它适用于 python2 、 python3 和 unicode 字符串中的 unicode 字符:


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)


声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM