如何解码字节对象的字符串表示形式?

3

我有一个包含编码字节的字符串:

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个回答

1
你可以使用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'

语法错误:字节只能包含ASCII字面字符。 - Sujil Devkota
这表明你的输入实际上是类似于"b'Output file 문í\x95\xadë¶\x84ì\x84\x9d.xlsx Created'",而不是我从你的问题中推断出的转义字符串。我认为此时是时候去修复发送给你这样混乱输入的任何东西了,老实说... - Zero Piraeus
https://www.dropbox.com/s/fmkrhy0pt29rdi3/%7BD15995AE-C51A-44DF-A53D-ED8A1CD4984C%7D.png.jpg?dl=0 - Sujil Devkota
请查看我的先前评论 - 一旦事情变得如此混乱,最好修复生成如此不愉快字符串的任何问题。 - Zero Piraeus
我自己已将其转换为字节 msg = bytes("输出文件 " + output_filename + " 已创建", 'utf-8') print(msg) 要通过popen().communicate()函数发送msg,该函数不支持原始的msg。在接收到communicate后,我会得到像上面那样的字节字符串列表。 - Sujil Devkota
或者你可以帮我解决这个问题: https://stackoverflow.com/questions/54890843/how-to-pass-unicode-text-message-through-popen-communicate - Sujil Devkota

1

根据您评论中提到的SyntaxError,当尝试打印时,您可能会遇到测试问题,因为您的控制台中设置了stdoutascii(您可能还会发现您的控制台不支持您尝试打印的一些字符)。您可以尝试以下内容将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')

属性错误:'OutStream'对象没有'buffer'属性。 - Sujil Devkota
1
@SujilDevkota - 很遗憾,我无法复制那个错误。可能存在其他环境因素(例如未包含在问题中的其他代码,某种我们没有预料到的操作系统/ shell组合等)。 - benvc

0

最终我找到了一个答案,使用一个函数将字符串转换为字节而不编码。给定字符串

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
一个简单的方法是假设初始字符串的所有字符都在[0,256)范围内,并映射到相同的Unicode值,这意味着它是一个Latin1编码的字符串。
然后转换就非常容易了:
str1[2:-1].encode('Latin1').decode('utf8')

谢谢,这个解决方案非常简短,比我找到的要容易得多。 - Sujil Devkota
但是有一件事情是,当我单独运行这段代码时它可以正常工作,但是在我的主程序中实现它时,经过Latin1编码的字符串会自动在任何\前面添加\,因此字符串中就会出现\,因此解码后只会删除单个斜杠。因此,上述代码变成了类似于str1[2:-1]。我认为为了转义\字符,Python正在添加另一个\。我该如何处理它? - Sujil Devkota

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接