2012-05-10 2 views
3

Я падаю в юникодном аду.Как распечатать 0xfb в python

Моя среда на Unix, питон 2.7.3

LC_CTYPE=zh_TW.UTF-8 
LANG=en_US.UTF-8 

Я пытаюсь сбросить шестигранные закодированные данные в удобочитаемом формате, здесь упрощено код

#! /usr/bin/env python 
# encoding:utf-8 
import sys 

s=u"readable\n" # previous result keep in unicode string 
s2="fb is not \xfb" # data read from binary file 
s += s2 

print s # method 1 
print s.encode('utf-8') # method 2 
print s.encode('utf-8','ignore') # method 3 
print s.decode('iso8859-1') # method 4 

# method 1-4 display following error message 
#UnicodeDecodeError: 'ascii' codec can't decode byte 0xfb 
# in position 0: ordinal not in range(128) 

f = open('out.txt','wb') 
f.write(s) 

Я просто хочу распечатайте 0xfb.

Я должен описать здесь больше. Ключ: s + = s2. Где будет сохранена моя предыдущая расшифрованная строка. И s2 - следующая строка, которая должна быть добавлена ​​в s.

Если я изменил его следующим образом, это происходит при записи файла.

s=u"readable\n" 
s2="fb is not \xfb" 
s += s2.decode('cp437') 
print s 
f=open('out.txt','wb') 
f.write(s) 
# UnicodeEncodeError: 'ascii' codec can't encode character 
# u'\u221a' in position 1: ordinal not in range(128) 

Я желаю результат out.txt является

readable 
fb is not \xfb 

или

readable 
fb is not 0xfb 

[Решение]

#! /usr/bin/env python 
# encoding:utf-8 
import sys 
import binascii 

def fmtstr(s): 
    r = '' 
    for c in s: 
     if ord(c) > 128: 
      r = ''.join([r, "\\x"+binascii.hexlify(c)]) 
     else: 
      r = ''.join([r, c]) 
    return r 

s=u"readable" 
s2="fb is not \xfb" 
s += fmtstr(s2) 
print s 
f=open('out.txt','wb') 
f.write(s) 
+0

Вы получаете сообщение об ошибке * same * при использовании 'encode', или вы получаете * 'utf8' кодек не может декодировать ... *? – kojiro

+3

\ xfb не UTF-8, так что это? –

+0

'\ xfb' - это двоичные данные, считываемые из двоичного файла. Я хочу показать как «0xfb или \ xfb для чтения человеком». –

ответ

3

Я сильно подозреваю, что ваш код на самом деле erroring out на предыдущей строке: s += s2 один. s2 - это всего лишь серия байтов, которая не может быть произвольно привязана к объекту unicode (который вместо этого представляет собой ряд кодовых точек).

Если бы вы умысел «\ XFB» представлять U+FB, LATIN SMALL LETTER U WITH CIRCUMFLEX, было бы лучше, чтобы назначить его, как это вместо:

s2 = u"\u00fb" 

Но вы сказали, что вы просто хотите распечатать \ xHH коды для управляющих символов. Если вы просто хотите, чтобы это было чем-то, что люди могли понять, что все еще делает очевидным, что специальные символы в строке, то может быть достаточно repr. Во-первых, не нужно s быть объектом unicode, потому что вы обрабатываете свои строки здесь как последовательность байтов, а не ряд кодовых точек.

s = s.encode('utf-8') 
s += s2 

print repr(s) 

Наконец, если вы не хотите, дополнительные котировки на внешней стороне, что repr добавляет, для хорошей симпатичной печати или что-то, что есть не простой встроенный способ сделать это в Python (что я знаю). Я использовал что-то подобное раньше:

import re 
controlchars_re = re.compile(r'[\x00-\x31\x7f-\xff]') 

def _show_control_chars(match): 
    txt = repr(match.group(0)) 
    return txt[1:-1] 

def escape_special_characters(s): 
    return controlchars_re.sub(_show_control_chars, s.replace('\\', '\\\\')) 

Вы можете довольно легко настроить controlchars_re регулярное выражение, чтобы определить, какие символы вы заботитесь о побеге.

+0

Спасибо, ваш код является почти ответом, если s2 читается, я просто хочу показать его как обычную строку, если он НЕ может, показать как hex. Фактически '' 'print s' '' предназначен только для отладки. Я просто хочу преобразовать в текстовый файл. –

+0

Возможно, вы просто захотите использовать 'repr (s)'.Это будет печатать строку таким образом, чтобы вы могли вставить ее обратно в Python и получить одно и то же значение, поэтому любые специальные символы получат обратное сбрасывание. –

+0

Если я написал escape_special_characters() сгенерированную строку в файл. Могу ли я прочитать их из файла обратно в исходные двоичные данные? –

Смежные вопросы