在Unicode数据中反斜杠转义ASCII控制字符绝对是一个有用的尝试。但不仅仅是对它们进行转义,而是在需要实际字符数据时正确地取消转义它们。
Python标准库应该有一种方法来做到这一点,但实际上没有。我提交了一个错误报告:
http://bugs.python.org/issue18679
但在此期间,可以使用translate和hackery来解决问题。
tm = dict((k, repr(chr(k))[1:-1]) for k in range(32))
tm[0] = r'\0'
tm[7] = r'\a'
tm[8] = r'\b'
tm[11] = r'\v'
tm[12] = r'\f'
tm[ord('\\')] = '\\\\'
b = u"Пример\n"
c = b.translate(tm)
print(c)
所有非反斜杠单字母控制字符都将使用\x##序列进行转义,但如果您需要对其进行其他处理,则可以使用翻译矩阵。尽管这种方法不会丢失任何信息,但它对我很有效。
但是将其取回也很麻烦,因为您不能仅使用translate将字符序列转换回单个字符。
d = c.encode('latin1', 'backslashreplace').decode('unicode_escape')
print(d)
您实际上需要使用latin1对映射到字节的字符进行单独编码,同时反斜杠转义latin1不知道的unicode字符,以便unicode_escape编解码器可以正确地重新组装所有内容。
更新:
所以我有一个情况,需要在python2.7和python3.3中都能工作。这是我所做的(埋藏在_compat.py模块中):
if isinstance(b"", str):
byte_types = (str, bytes, bytearray)
text_types = (unicode, )
def uton(x): return x.encode('utf-8', 'surrogateescape')
def ntob(x): return x
def ntou(x): return x.decode('utf-8', 'surrogateescape')
def bton(x): return x
else:
byte_types = (bytes, bytearray)
text_types = (str, )
def uton(x): return x
def ntob(x): return x.encode('utf-8', 'surrogateescape')
def ntou(x): return x
def bton(x): return x.decode('utf-8', 'surrogateescape')
escape_tm = dict((k, ntou(repr(chr(k))[1:-1])) for k in range(32))
escape_tm[0] = u'\0'
escape_tm[7] = u'\a'
escape_tm[8] = u'\b'
escape_tm[11] = u'\v'
escape_tm[12] = u'\f'
escape_tm[ord('\\')] = u'\\\\'
def escape_control(s):
if isinstance(s, text_types):
return s.translate(escape_tm)
else:
return s.decode('utf-8', 'surrogateescape').translate(escape_tm).encode('utf-8', 'surrogateescape')
def unescape_control(s):
if isinstance(s, text_types):
return s.encode('latin1', 'backslashreplace').decode('unicode_escape')
else:
return s.decode('utf-8', 'surrogateescape').encode('latin1', 'backslashreplace').decode('unicode_escape').encode('utf-8', 'surrogateescape')
bytes
)不包含 Unicode 字符,它们只包含字节。这些字节可能是以特定编码存储的 Unicode 代码点,但它们仍然只是字节。如果您想存储 Unicode,请使用unicode
。如果您想要字节,请使用bytes
- 但这样您就没有 Unicode,只有没有 UTF-* 信息的字节。它可能像一些奇怪的8位代码页一样。另请参阅 http://nedbatchelder.com/text/unipain.html,其中提供了一些见解和一般方法。 - user395760