2012-05-10 2 views
3

나는 유니 코드 지옥에 떨어지고 있습니다. 유닉스에서의파이썬에서 0xfb를 출력하는 방법

내 환경, 파이썬 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'입니다. s는 이전에 디코딩 된 문자열을 유지합니다. 그리고 s2는 s에 추가해야하는 다음 문자열입니다.

다음과 같이 수정하면 쓰기 파일에서 발생합니다. 내가 out.txt의 결과를 원하는

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) 

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

'인코딩'을 사용하거나 * 'utf8'코덱을 디코딩 할 수없는 경우 * 같은 * 오류 메시지가 표시됩니까? *? – kojiro

+3

\ xfb는 UTF-8이 아니므로 무엇입니까? –

+0

'\ xfb'는 바이너리 파일에서 읽은 바이너리 데이터입니다. 나는 '0xfb 또는 인간이 읽을 수있는 \ xfb'로 표시하려고합니다. –

답변

3

내가 강력하게 코드가 실제로 erroring 것으로 의심 이전 줄에서 : s += s2 하나. s2는 일련의 바이트이며 유니 코드 객체 (임의의 코드 포인트 대신)에 임의로 추가 할 수 없습니다. 당신이 U+FB, LATIN SMALL LETTER U WITH CIRCUMFLEX를 대표하는 '\의 xfb'를 구성했다면

는,이 대신에 같이 할당하는 것이 더했을 것이다 :

s2 = u"\u00fb" 

그러나 당신은 당신이 그냥 \ xHH을 인쇄 할 것이라고 말했다 제어 문자를위한 코드. 캐릭터가 특수 문자가 문자열에 있다는 것이 아직도 명백한 인간이 이해할 수있는 것일 뿐이라면 repr이면 충분할 것입니다. 먼저 s을 유니 코드 객체로 사용하지 마십시오. 여기에서 문자열을 일련의 코드 포인트가 아닌 일련의 바이트로 처리하기 때문입니다. 당신이 repr 좋은 꽤 인쇄 또는 무엇 이건, 추가하는 외부에 별도의 따옴표를하지 않으려면

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

print repr(s) 

마지막으로, (내가 아는) 파이썬에서 그렇게 할 수있는 간단한 내장 방법이 아니다. 당신은 아주 쉽게 탈출에 대해 걱정하는 문자를 정의 할 controlchars_re 정규식을 조정할 수

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('\\', '\\\\')) 

: 나는 전에이 같은 것을 사용했습니다.

+0

고마워요, 당신의 코드는 거의 대답입니다. s2가 읽을 수 있다면, 나는 단지 그것을 정상적인 문자열로 보여주고 싶을 것입니다. 실제로 '' 'print' ''는 단지 디버그를위한 것입니다. 텍스트 파일로 변환하고 싶습니다. –

+0

'repr (s)'을 사용하고 싶을 수도 있습니다.이렇게하면 문자열을 파이썬에 붙여 넣을 수 있고 동일한 값을 얻을 수있는 방식으로 문자열을 출력하므로 특수 문자가 백 슬래시로 표시됩니다. –

+0

escape_special_characters() 생성 된 문자열을 파일에 썼다면. 파일에서 원래의 바이너리 데이터로 다시 읽을 수 있습니까? –

관련 문제