Как декодировать строковое представление объекта байтов? - PullRequest
0 голосов
/ 26 февраля 2019

У меня есть строка, которая содержит закодированные байты внутри:

str1 = "b'Output file \xeb\xac\xb8\xed\x95\xad\xeb\xb6\x84\xec\x84\x9d.xlsx Created'"

Я хочу ее декодировать, но не могу, поскольку она стала строкой.Поэтому я хочу спросить, есть ли какой-нибудь способ, которым я могу преобразовать его в

str2 = b'Output file \xeb\xac\xb8\xed\x95\xad\xeb\xb6\x84\xec\x84\x9d.xlsx Created'

Здесь str2 - это bytes объект, который я могу легко декодировать, используя

str2.decode('utf-8')

дляполучить окончательный результат:

'Output file 문항분석.xlsx Created'

Ответы [ 4 ]

0 голосов
/ 28 февраля 2019

Простой способ - предположить, что все символы исходных строк находятся в диапазоне [0,256) и отображаются на одно и то же значение Unicode, что означает, что это строка в кодировке Latin1.

Преобразованиетогда тривиально:

str1[2:-1].encode('Latin1').decode('utf8')
0 голосов
/ 26 февраля 2019

На основании SyntaxError, упомянутой в ваших комментариях, у вас может возникнуть проблема с тестированием при попытке печати из-за того, что stdout имеет значение ascii в вашей консоли (и вы также можете обнаружить, что ваша консольне поддерживает некоторые символы, которые вы, возможно, пытаетесь напечатать).Вы можете попробовать что-то вроде следующего, чтобы установить sys.stdout в utf-8 и посмотреть, что будет печатать ваша консоль (просто используя строковый срез и encode ниже, чтобы получить байты, а не подход ast.literal_eval, который уже был предложен):

import codecs
import sys

sys.stdout = codecs.getwriter('utf-8')(sys.stdout.buffer)

s = "b'Output file \xeb\xac\xb8\xed\x95\xad\xeb\xb6\x84\xec\x84\x9d.xlsx Created'"
b = s[2:-1].encode().decode('utf-8')
0 голосов
/ 28 февраля 2019

Наконец-то я нашел ответ, в котором я использую функцию для преобразования строки в байты без кодирования. Полученная строка

str1 = "b'Output file \xeb\xac\xb8\xed\x95\xad\xeb\xb6\x84\xec\x84\x9d.xlsx Created'"

теперь я беру внутри себя только фактически закодированный текст

str1[2:-1]

и передать это функции, которая преобразует строку в байты без кодирования ее значений

import struct
def rawbytes(s):
    """Convert a string to raw bytes without encoding"""
    outlist = []
    for cp in s:
        num = ord(cp)
        if num < 255:
            outlist.append(struct.pack('B', num))
        elif num < 65535:
            outlist.append(struct.pack('>H', num))
        else:
            b = (num & 0xFF0000) >> 16
            H = num & 0xFFFF
            outlist.append(struct.pack('>bH', b, H))
    return b''.join(outlist)

Таким образом, вызов функции преобразует ее в байтыкоторый затем декодируется

rawbytes(str1[2:-1]).decode('utf-8')

даст правильный вывод

'Output file 문항분석.xlsx Created'

0 голосов
/ 26 февраля 2019

Вы можете использовать ast.literal_eval:

>>> print(str1)
b'Output file \xeb\xac\xb8\xed\x95\xad\xeb\xb6\x84\xec\x84\x9d.xlsx Created'
>>> type(str1)
<class 'str'>

>>> from ast import literal_eval
>>> literal_eval(str1).decode('utf-8')
'Output file 문항분석.xlsx Created'
...