Как разбить строку с символами ASCII (\ u9078) в Python

При преобразовании свойств в JSON он добавил дополнительную обратную косую черту в символ ASCII. Как этого избежать, см. Код ниже.

Входной файл (sample.properties)

property.key.CHOOSE=\u9078\u629e

Код

import json
def convertPropertiesToJson(fileName, outputFileName, sep='=', comment_char='#'):
    props = {}
    with open(fileName, "r") as f:
        for line in f:
            l = line.strip()
            if l and not l.startswith(comment_char):
                innerProps = {}
                keyValueList = l.split(sep)
                key = keyValueList[0].strip()
                keyList = key.split('.')
                value = sep.join(keyValueList[1:]).strip()
                if keyList[1] not in props:
                    props[keyList[1]] = {}
                innerProps[keyList[2]] = value
                props[keyList[1]].update(innerProps)
    with open(outputFileName, 'w') as outfile:
        json.dump(props, outfile)

convertPropertiesToJson("sample.properties", "sample.json")

Выход: (sample.json)

{"key": {"CHOOSE": "\\u9078\\u629e"}}

Ожидаемый результат:

{"key": {"CHOOSE": "\u9078\u629e"}}

Вы уверены, что это лишняя обратная косая черта? На первый взгляд, я мог бы предположить, что две люфты необходимы для визуализации буквальной обратной косой черты перед u в \u. В противном случае \u просто ускользает от u, что, вероятно, дает простой u.

Tim Biegeleisen 16.03.2018 06:29

Да, это так. Он предоставил минимальный тестовый пример.

0x01 16.03.2018 06:36

см. это: stackoverflow.com/questions/49315872/…

Rahul 16.03.2018 09:43
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
3
437
3

Ответы 3

Проблема, похоже, в том, что вы сохранили символы Юникода, которые представлены как экранированные строки. В какой-то момент вы должны их расшифровать.

Изменение

l = line.strip()

в (для Python 2.x)

l = line.strip().decode('unicode-escape')

в (для Python 3.x)

l = line.strip().encode('ascii').decode('unicode-escape')

дает желаемый результат:

{"key": {"CHOOSE": "\u9078\u629e"}}

это не будет работать в python3, как специально запрошено op.

Rahul 16.03.2018 07:04

Python3: .encode('ascii').decode('unicode-escape')

VPfB 16.03.2018 08:27

Спасибо за комментарии, я отредактировал свой ответ соответственно для потомков.

0x01 16.03.2018 08:35

Я не знаю решения вашей проблемы, но я выяснил, где возникает проблема.

with open('sample.properties', encoding='utf-8') as f:
    for line in f:
        print(line)
        print(repr(line))
        d = {}
        d['line'] = line
        print(d)

out:
property.key.CHOOSE=\u9078\u629e
'property.key.CHOOSE=\\u9078\\u629e'
{'line': 'property.key.CHOOSE=\\u9078\\u629e'}

Я не знаю, как добавление в словарь добавляет повтора строки.

Проблема в том, что ввод читается как есть, а \u копируется буквально двумя символами. Самое простое исправление, вероятно, следующее:

with open(fileName, "r", encoding='unicode-escape') as f:

Это будет декодировать экранированные символы Unicode.

Этот! Воспользуйтесь этим решением. Это тот ответ, который я хотел дать раньше, но у меня он не сработал, поскольку раньше я ошибочно запускал код с python2 вместо python3.

0x01 16.03.2018 08:38

Я тоже искал ответа. Я задал аналогичный вопрос, просто посмотрите: stackoverflow.com/questions/49315872/…

Rahul 16.03.2018 09:43

Другие вопросы по теме