Преобразовать строку, содержащую управляющие символы, в диктовку - PullRequest
2 голосов
/ 30 апреля 2019

Мне нужно преобразовать строку Python, которая представляет dict в python dict.Строка может содержать любое допустимое представление dict, включая пути в стиле Windows (с обратной косой чертой), например,

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

Мне понадобится универсальная строка str для функции dict convert, так что это всего лишь пример исходной строки,который не работает.Исходная строка может исходить из внешних источников.Было бы предпочтительнее совместимое с Python 2/3 решение.

Я уже попробовал данные ответы:

json.loads не работает (даже если я переформатирую строку в синтаксис json): вызывает исключение

ast.literal_eval не работает: в этом примере он помещает символ табуляции в результат

eval: тот же результат, что и ast.literal_eval

Ответы [ 3 ]

1 голос
/ 01 мая 2019

Edit3: после операции измените образец строки для двойной обратной косой черты, это проще и не нужно использовать регулярное выражение:

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

предыдущий ответ, которого недостаточно Редактировать: простой способ преобразования строки в raw - это использование repr() или "%r"

Вот одношаговое решение, кредиты идут на Nishanth Amuluru и Джед Александр 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"}'
1 голос
/ 30 апреля 2019

Я бы поставил хак на строку, чтобы заменить 'c:' в качестве необработанного строкового литерала r'c: '

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

Результат:

{'baselocaldir': 'c:\\tmp\\SrcTmp\\RepManager'}
0 голосов
/ 01 мая 2019

Мое (возможно, не самое элегантное) решение:

Но это работает на 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)


...