2

在某些时候,我们的 python 脚本会收到这样的字符串:

In [1]: ab = 'asd\xeffe\ctive'

In [2]: print ab
asd�fe\ctve \ \\ \\\k\\\

数据已损坏,我们需要转义 \x 才能正确解释为 \x 但 \c 在字符串中没有特殊含义,因此必须完好无损。

到目前为止,我找到的最接近的解决方案是执行以下操作:

In [1]: ab = 'asd\xeffe\ctve \\ \\\\ \\\\\\k\\\\\\'

In [2]: print ab.encode('string-escape').replace('\\\\', '\\').replace("\\'", "'")

asd\xeffe\ctve \ \\ \\\k\\\

从 IPython 获取的输出,我假设 ab 是一个字符串而不是 unicode 字符串(在后一种情况下,我们将不得不这样做:

def escape_string(s):
    if isinstance(s, str):
        s = s.encode('string-escape').replace('\\\\', '\\').replace("\\'", "'")
    elif isinstance(s, unicode):
        s = s.encode('unicode-escape').replace('\\\\', '\\').replace("\\'", "'")
    return s
4

4 回答 4

3

\xhh是一个转义字符,\x被视为此转义的开始。

于 2012-10-11T16:11:17.407 回答
2

反斜杠引入了“转义序列”。\x特别允许您指定一个字节,它以 x 后的两个十六进制数字形式给出。ef是两个十六进制数字,因此不会出错。将反斜杠加倍以将其转义,或使用原始字符串r"\xeffective"

编辑:虽然 Python 控制台可能会向您显示'\\',但这正是您所期望的。你只是说你期待别的东西,因为你混淆了字符串及其表示。它是一个包含单个反斜杠的字符串。如果你用 输出它print,你会看到一个反斜杠。

但是字符串文字格式'\'不正确(未关闭,因为\'是撇号,而不是反斜杠和字符串结尾文字),因此repr在交互式 shell 中格式化结果的 , 不会产生它。相反,它会生成一个字符串文字,您可以将其粘贴到 Python 源代码中并获取相同的字符串对象。例如,len('\\') == 1

于 2012-10-11T16:13:50.877 回答
2

'\\'是一样的'\x5c'。将反斜杠字符写为Python 字符串文字只是两种不同的方式。

这些文字字符串:r'\c', '\\c', '\x5cc','\x5c\x63'是内存中的相同 str对象。

'\xef'是单个字节(239作为整数),但r'\xef'(与 相同'\\xef')是 4 字节字符串:'\x5c\x78\x65\x66'.

如果s[0]返回'\xef',那么它就是s对象实际包含的内容。如果是错误的,则修复数据源。


注意:string-escape还有转义\n之类的:

>>> print u'''\xef\c\\\N{SNOWMAN}"'\
... ☃\u2603\"\'\n\xa0'''.encode('unicode-escape')
\xef\\c\\\u2603"'\u2603\u2603"'\n\xa0
>>> print b'''\xef\c\\\N{SNOWMAN}"'\
... ☃\u2603\"\'\n\xa0'''.encode('string-escape')
\xef\\c\\\\N{SNOWMAN}"\'\xe2\x98\x83\\u2603"\'\n\xa0

backslashreplace仅用于导致UnicodeEncodeError

>>> print u'''\xef\c\\\N{SNOWMAN}"'\
... ☃\u2603\"\'\n\xa0'''
ï\c\☃"'☃☃"'

>>> print b'''\xef\c\\\N{SNOWMAN}"'\
... ☃\u2603\"\'\n\xa0'''
�\c\\N{SNOWMAN}"'☃\u2603"'
�
>>> print u'''\xef\c\\\N{SNOWMAN}"'\
... ☃\u2603\"\'\n\xa0'''.encode('ascii', 'backslashreplace')
\xef\c\\u2603"'\u2603\u2603"'
\xa0
>>> print b'''\xef\c\\\N{SNOWMAN}"'\
... ☃\u2603\"\'\n\xa0'''.decode('latin1').encode('ascii', 'backslashreplace')
\xef\c\\N{SNOWMAN}"'\xe2\x98\x83\u2603"'
\xa0
于 2012-10-11T16:40:39.573 回答
1

转义序列表示字符串中的\xUnicode 字符,ef并被解释为十六进制代码。您可以通过添加额外的 来清理字符串\,或者将其设为原始字符串 ( r'\xeffective')。

>>> r'\xeffective'[0]
'\\'

编辑:您可以使用以下技巧转换现有字符串:

>>> a = '\xeffective'
>>> b = repr(a).strip("'")
>>> b
'\\xeffective'
于 2012-10-11T16:17:27.487 回答