如何将repr转换为编码字符串

时间:2016-07-14 22:15:45

标签: python python-3.x

我有 if (requestCode == PermissionA.requestCode) (来自我无法修复的文件):

str

这接近于在utf8中编码的字符串的repr:

In [131]: s
Out[131]: '\\xce\\xb8Oph'

我需要原始的编码字符串。我可以用

做到
In [132]: repr('θOph'.encode('utf8'))
Out[132]: "b'\\xce\\xb8Oph'"

但我会......伤心?如果没有更简单的选择来获得它。还有更好的方法吗?

4 个答案:

答案 0 :(得分:4)

你的解决方案没问题,唯一的问题是当eval与任意输入一起使用时是危险的。安全的替代方法是使用ast.literal_eval

>>> s = '\\xce\\xb8Oph'
>>> from ast import literal_eval
>>> literal_eval("b'{}'".format(s)).decode('utf8')
'\u03b8Oph'

使用eval,您需要:

>>> eval("b'{}'".format("1' and print('rm -rf /') or b'u r owned")).decode('utf8')
rm -rf /
'u r owned'

由于ast.literal_eval与文字的repr相反,我想这就是您要找的内容。

[updade]

如果您有一个带有转义unicode的文件,您可能需要按照Ginger ++的答案中的建议使用unicode_escape编码打开它。我会保留我的答案,因为问题是“如何将repr转换为编码字符串”,而不是“如何使用转义的unicode解码文件”。

答案 1 :(得分:3)

只需使用unicode_escape编码打开您的文件,例如:

with open('name', encoding="unicode_escape") as f:
    pass # your code here

原始答案:

>>> '\\xce\\xb8Oph'.encode('utf-8').decode('unicode_escape')
'θOph'

如果您以二进制模式而不是文本模式读取文件,则可以将该编码移除到UTF-8:

>>> b'\\xce\\xb8Oph'.decode('unicode_escape')
'θOph'

答案 2 :(得分:2)

不幸的是,这确实存在问题。它在这里轻轻地杀了你。

我只能想到:

s = '\\xce\\xb8Oph\\r\\nMore test\\t\\xc5\\xa1'
n = ""
x = 0
while x!=len(s):
    if s[x]=="\\":
        sx = s[x+1:x+4]
        marker = sx[0:1]
        if   marker=="x": n += chr(int(sx[1:], 16)); x += 4
        elif marker in ("'", '"', "\\", "n", "r", "v", "t", "0"):
            # Pull this dict out of a loop to speed things up
            n += {"'": "'", '"': '"', "\\": "\\", "n": "\n", "r": "\r", "t": "\t", "v": "\v", "0": "\0"}[marker]
            x += 2
        else: n += s[x]; x += 1
    else: n += s[x]; x += 1
print repr(n), repr(s)
print repr(n.decode("UTF-8"))

可能还有其他一些技巧可以解决这个问题,但目前这就是我所得到的。

答案 3 :(得分:0)

在GingerPlusPlus的回答中做出 teeny 改进:

import tempfile                                                        

with tempfile.TemporaryFile(mode='rb+') as f:                          
    f.write(r'\xce\xb8Oph'.encode())                                   
    f.flush()                                                          
    f.seek(0)                                                          

    print(f.read().decode('unicode_escape').encode('latin1').decode()) 

如果您以二进制模式打开文件(即rb,因为您正在阅读,我添加了+,因为我还写了该文件)您可以跳过第一次encode来电。它仍然很尴尬,因为你必须通过解码/编码跳跃,但你至少要避免第一次编码调用。