2012-12-22 1 views
0

문자열에서 바이트 순서 표시를 제거해야합니다. BOM을 찾을 코드가 이미 있지만 실제 문자열에서 제거해야합니다.파이썬의 문자열에서 처음 2 바이트 제거

예를 들어 설명해주십시오. BOM은 feff이고 길이가 2 바이트이므로 문자열의 처음 2 바이트가 최종 문자열에 나타나서는 안됩니다. 그러나 파이썬 문자열 스트립 핑을 사용하면 문자열에서 너무 많은 스트립이 제거됩니다.

코드 스 니펫 :

print len(bom) 
print as_hex(bom) 
print string 
print as_hex(string) 
string = string[len(bom):] 
print string 
print as_hex(string) 

출력 :

2 
feff 
Organ 
feff4f7267616e 
rgan 
7267616e 

무엇을 얻을 수 있도록 노력하겠습니다 것은 :

2 
feff 
Organ 
feff4f7267616e 
Organ 
4f7267616e 

as_hex() 기능은 단지 진수로 문자를 출력 ("".join('%02x' % ord(c) for c in bytes)) .

+0

사용중인 'bom' 변수는 무엇입니까? 길이가 틀린 것 같습니다. – BrenBarn

+0

'len (bom)'을 인쇄 해 보셨습니까? – Rubens

+1

4 자리 16 진수 문자는 실제로 2 바이트입니다. 왜 네가 스트라이핑을하는거야? – goncalopp

답변

4

유니 코드 문자열 개체가 있다고 생각합니다. (파이썬 3을 사용한다면 확실히 할 수 있습니다.) as_hex 함수는 첫 번째 문자에는 "fe"를, 두 번째 문자에는 "ff"를 출력하지 않습니다. 문자열의 첫 번째 유니 코드 문자에 대해 "feff"가 출력됩니다. 예 (파이썬 3)의 경우 :

>>> mystr = "\ufeffHello world." 
>>> mystr[0] 
'\ufeff' 
>>> '%02x' % ord(mystr[0]) 
'feff' 

당신이 중 하나는 하나의 유니 코드 문자를 제거하거나 대신 bytes 객체에 문자열을 저장하고 2 바이트를 제거해야합니다.

(이것은 len (bom)이 2 인 이유를 설명하지 않으며 코드가 더 이상 표시되지 않으면 알 수 없습니다.) BOM은 유니 코드 문자열이 아닌 list 또는 bytes 개체라고 생각합니다. string가있는 동안)


내 대답은 위의 파이썬 3 가정,하지만 난 당신이 그 바탕으로 파이썬 2를 사용하고 인쇄 문에서 실현 한, 나는 bom이 ASCII 문자열임을 추측에는 요 유니 코드 문자열. print x 대신 print repr(x)을 사용하면 유니 코드와 ASCII 문자열의 차이점을 알 수 있습니다.

+1

이것은 내가 생각한 것입니다. 또한 유니 코드 문자열에 BOM을 포함하는 것은 이치에 맞지 않으므로 문자열이 생성 된 곳의 어딘가에 문제가있을 수 있습니다. BOM은 인코딩 된 문자열에서만 의미가 있습니다. – BrenBarn

+0

실제로 문자열이 아닌 텍스트 파일 또는 스트림의 엔디 언 (바이트 순서)을 나타내는 BOM이 아닙니까? 또한 2 바이트 이상 될 수 있습니다. 예를 들어 UTF-8의 경우 '0xEF, 0xBB, 0xBF'바이트 시퀀스입니다. – martineau

+0

당신의 답은 저를 해결책으로 이끌었습니다. 'string = bytearray (string, encoding = self.encoding) [len (bom) :]. decode (self.encoding)' – dominik

0

올바른 코덱을 사용하면 BOM이 자동으로 처리됩니다. utf-8-sigutf16을 사용하여 디코딩하면 주요 BOM이 제거됩니다. 그들과 함께 인코딩하면 BOM이 추가됩니다. BOM을 원하지 않으면 utf-8, utf-16le 또는 utf-16be을 사용하십시오.

unicode_str = u'test' 
utf8_w_bom = unicode_str.encode('utf-8-sig') 
utf16_w_bom = unicode_str.encode('utf16') 
utf8_wo_bom = unicode_str.encode('utf-8') 
utf16_wo_bom = unicode_str.encode('utf-16le') 
print repr(utf8_w_bom) 
print repr(utf16_w_bom) 
print repr(utf8_wo_bom) 
print repr(utf16_wo_bom) 
print repr(utf8_w_bom.decode('utf-8-sig')) 
print repr(utf16_w_bom.decode('utf16')) 
print repr(utf8_wo_bom.decode('utf-8-sig')) 
print repr(utf16_wo_bom.decode('utf16')) 

출력 콘솔, 소켓, 파일에 기록 할 때 당신은 일반적으로 프로그램에 텍스트 데이터를 읽을 때 유니 코드로 디코딩하고, 바이트로 인코딩해야

:

'\xef\xbb\xbftest' 
'\xff\xfet\x00e\x00s\x00t\x00' 
'test' 
't\x00e\x00s\x00t\x00' 
u'test' 
u'test' 
u'test' 
u'test' 

주 디코드시 utf16은 BOM이 없으면 기본 바이트 순서를 취합니다.

관련 문제