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

'\\'と同じ'\x5c'です。バックスラッシュ文字をPython 文字列リテラルとして記述するには、2 つの異なる方法があります。

これらのリテラル文字列: r'\c''\\c'、は'\x5cc'、メモリ内の同一のオブジェクトです。'\x5c\x63' str

'\xef'は 1 バイト (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 に答える
2

バックスラッシュは「エスケープ シーケンス」を導入します。\x具体的には、x の後に 2 桁の 16 進数として指定されるバイトを指定できます。efは 2 桁の 16 進数であるため、エラーは発生しません。バックスラッシュを二重にしてエスケープするか、生の文字列を使用しますr"\xeffective"

編集: Python コンソールには が表示される場合がありますが'\\'、これまさにあなたが期待するものです。文字列とその表現を混同しているため、何か他のものを期待していると言っているだけです。バックスラッシュを 1 つ含む文字列です。で出力するとprint、単一のバックスラッシュが表示されます。

しかし、文字列リテラルは形式が正しくありません ( はアポストロフィであり、バックスラッシュや文字列リテラルの終わりではない'\'ため閉じられていません) ため、対話型シェルで結果をフォーマットする はそれを生成しません。代わりに、Python ソース コードに貼り付けて同じ文字列オブジェクトを取得できる文字列リテラルを生成します。たとえば、.\'reprlen('\\') == 1

于 2012-10-11T16:13:50.877 に答える
1

エスケープ シーケンスは文字列内の\xUnicode 文字を表し、ef16 進コードとして解釈されます。を追加して文字列をサニタイズ\するか、生の文字列 ( r'\xeffective') にすることができます。

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

編集:次のハックを使用して既存の文字列を変換できます:

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