如何在Python3中解码(';字符串转义';)?

如何在Python3中解码(';字符串转义';)?,python,python-3.x,escaping,Python,Python 3.x,Escaping,我有一些转义字符串需要取消转义。我想用Python来做这件事 例如,在python2.7中,我可以这样做: >>> "\\123omething special".decode('string-escape') 'Something special' >>> 如何在Python3中实现它?这不起作用: >>> b"\\123omething special".decode('string-escape') Traceback (most

我有一些转义字符串需要取消转义。我想用Python来做这件事

例如,在python2.7中,我可以这样做:

>>> "\\123omething special".decode('string-escape')
'Something special'
>>> 
如何在Python3中实现它?这不起作用:

>>> b"\\123omething special".decode('string-escape')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
LookupError: unknown encoding: string-escape
>>> 
并将其转化为:

"support@psiloc.com"

完成转换后,我将探测我拥有的字符串是否以UTF-8或UTF-16编码。

您必须使用
unicode\u escape

>>> b"\\123omething special".decode('unicode_escape')
如果改为从
str
对象开始(相当于python 2.7 unicode),则需要先编码到字节,然后使用
unicode\u escape
进行解码

如果需要字节作为最终结果,则必须再次编码为合适的编码(
.encode('latin1')
,例如,如果需要保留文字字节值,则必须将前256个Unicode代码点映射为1对1)

您的示例实际上是带有转义符的UTF-16数据。从
unicode\u escape
解码,返回到
latin1
以保留字节,然后从
utf-16-le
(utf 16小端无BOM):


您必须改用
unicode\u escape

>>> b"\\123omething special".decode('unicode_escape')
如果改为从
str
对象开始(相当于python 2.7 unicode),则需要先编码到字节,然后使用
unicode\u escape
进行解码

如果需要字节作为最终结果,则必须再次编码为合适的编码(
.encode('latin1')
,例如,如果需要保留文字字节值,则必须将前256个Unicode代码点映射为1对1)

您的示例实际上是带有转义符的UTF-16数据。从
unicode\u escape
解码,返回到
latin1
以保留字节,然后从
utf-16-le
(utf 16小端无BOM):


您不能在字节字符串上使用
unicode\u escape
(或者更确切地说,您可以,但它并不总是返回与Python 2上的
string\u escape
相同的内容)–小心

此函数使用正则表达式和自定义替换逻辑实现
string\u escape

def unescape(text):
    regex = re.compile(b'\\\\(\\\\|[0-7]{1,3}|x.[0-9a-f]?|[\'"abfnrt]|.|$)')
    def replace(m):
        b = m.group(1)
        if len(b) == 0:
            raise ValueError("Invalid character escape: '\\'.")
        i = b[0]
        if i == 120:
            v = int(b[1:], 16)
        elif 48 <= i <= 55:
            v = int(b, 8)
        elif i == 34: return b'"'
        elif i == 39: return b"'"
        elif i == 92: return b'\\'
        elif i == 97: return b'\a'
        elif i == 98: return b'\b'
        elif i == 102: return b'\f'
        elif i == 110: return b'\n'
        elif i == 114: return b'\r'
        elif i == 116: return b'\t'
        else:
            s = b.decode('ascii')
            raise UnicodeDecodeError(
                'stringescape', text, m.start(), m.end(), "Invalid escape: %r" % s
            )
        return bytes((v, ))
    result = regex.sub(replace, text)
def unescape(文本):
regex=re.compile(b'\\\\\\\\\[0-7]{1,3}x.[0-9a-f]?[\''abfnrt].$))
def更换(m):
b=m组(1)
如果len(b)==0:
raise VALUERROR(“无效字符转义:'\\'.”)
i=b[0]
如果i==120:
v=int(b[1:],16)

elif 48您不能在字节字符串上使用
unicode\u escape
(或者更确切地说,您可以,但它并不总是返回与Python 2上的
string\u escape
相同的内容)-小心

此函数使用正则表达式和自定义替换逻辑实现
string\u escape

def unescape(text):
    regex = re.compile(b'\\\\(\\\\|[0-7]{1,3}|x.[0-9a-f]?|[\'"abfnrt]|.|$)')
    def replace(m):
        b = m.group(1)
        if len(b) == 0:
            raise ValueError("Invalid character escape: '\\'.")
        i = b[0]
        if i == 120:
            v = int(b[1:], 16)
        elif 48 <= i <= 55:
            v = int(b, 8)
        elif i == 34: return b'"'
        elif i == 39: return b"'"
        elif i == 92: return b'\\'
        elif i == 97: return b'\a'
        elif i == 98: return b'\b'
        elif i == 102: return b'\f'
        elif i == 110: return b'\n'
        elif i == 114: return b'\r'
        elif i == 116: return b'\t'
        else:
            s = b.decode('ascii')
            raise UnicodeDecodeError(
                'stringescape', text, m.start(), m.end(), "Invalid escape: %r" % s
            )
        return bytes((v, ))
    result = regex.sub(replace, text)
def unescape(文本):
regex=re.compile(b'\\\\\\\\\[0-7]{1,3}x.[0-9a-f]?[\''abfnrt].$))
def更换(m):
b=m组(1)
如果len(b)==0:
raise VALUERROR(“无效字符转义:'\\'.”)
i=b[0]
如果i==120:
v=int(b[1:],16)
elif 48旧的“字符串转义”编解码器将ByTestRing映射到ByTestRing,关于如何使用此类编解码器,存在很多争论,因此目前无法通过标准编码/解码接口使用

但是,代码仍然存在于C-API中(如
PyBytes\u En/decodeScape
),并且仍然通过未记录的
codecs.escape\u encode
codecs.escape\u decode
向Python公开

>>> import codecs
>>> codecs.escape_decode(b"ab\\xff")
(b'ab\xff', 6)
>>> codecs.escape_encode(b"ab\xff")
(b'ab\\xff', 3)
这些函数返回转换后的
字节
对象,加上一个数字,指示处理了多少字节。。。你可以忽略后者

>>> value = b's\\000u\\000p\\000p\\000o\\000r\\000t\\000@\\000p\\000s\\000i\\000l\\000o\\000c\\000.\\000c\\000o\\000m\\000'
>>> codecs.escape_decode(value)[0]
b's\x00u\x00p\x00p\x00o\x00r\x00t\x00@\x00p\x00s\x00i\x00l\x00o\x00c\x00.\x00c\x00o\x00m\x00'
旧的“字符串转义”编解码器将ByTestRing映射到ByTestRing,关于如何使用此类编解码器,人们一直存在很多争论,因此目前无法通过标准编码/解码接口使用

但是,代码仍然存在于C-API中(如
PyBytes\u En/decodeScape
),并且仍然通过未记录的
codecs.escape\u encode
codecs.escape\u decode
向Python公开

>>> import codecs
>>> codecs.escape_decode(b"ab\\xff")
(b'ab\xff', 6)
>>> codecs.escape_encode(b"ab\xff")
(b'ab\\xff', 3)
这些函数返回转换后的
字节
对象,加上一个数字,指示处理了多少字节。。。你可以忽略后者

>>> value = b's\\000u\\000p\\000p\\000o\\000r\\000t\\000@\\000p\\000s\\000i\\000l\\000o\\000c\\000.\\000c\\000o\\000m\\000'
>>> codecs.escape_decode(value)[0]
b's\x00u\x00p\x00p\x00o\x00r\x00t\x00@\x00p\x00s\x00i\x00l\x00o\x00c\x00.\x00c\x00o\x00m\x00'

至少在我的情况下,这相当于:

Py2: my_input.decode('string_escape')
Py3: bytes(my_input.decode('unicode_escape'), 'latin1')
convertutils.py:

def string_escape(my_bytes):
    return bytes(my_bytes.decode('unicode_escape'), 'latin1')

至少在我的情况下,这相当于:

Py2: my_input.decode('string_escape')
Py3: bytes(my_input.decode('unicode_escape'), 'latin1')
convertutils.py:

def string_escape(my_bytes):
    return bytes(my_bytes.decode('unicode_escape'), 'latin1')

如果要对转义序列进行str-to-str解码,则输入和输出均为Unicode:

def string_转义(s,encoding='utf-8'):
将(s.encode('latin1')#返回到字节,这是“unicode转义”所要求的
.decode(“unicode-escape”)#执行实际的八进制转义解码
.encode('latin1')#1:1映射回字节
.解码(编码)#解码原始编码
测试:

>>字符串\u转义('\\123omething special')
“一些特别的东西”
>>>字符串\u转义(r's\000u\000p\000p\000o\000r\000t\000@'
r'\000p\000s\000i\000l\000o\000c\000.\000c\000o\000m\000',
‘utf-16-le’)
'support@psiloc.com'

如果您想对转义序列进行解码,那么输入和输出都是Unicode:

def string_转义(s,encoding='utf-8'):
将(s.encode('latin1')#返回到字节,这是“unicode转义”所要求的
.decode(“unicode-escape”)#执行实际的八进制转义解码
.encode('latin1')#1:1映射回字节
.解码(编码)#解码原始编码
测试:

>>字符串\u转义('\\123omething special')
“一些特别的东西”
>>>字符串\u转义(r's\000u\000p\000p\000o\000r\000t\000@'
r'\000p\000s\000i\000l\000o\000c\000.\000c\000o\000m\000',
‘utf-16-le’)
'support@psiloc.com'
py2

py3

py2

py3


这将我的二进制对象转换为Unicode对象。我想把它保留下来