0

Redshift 데이터베이스에서 데이터를 가져 오는 Django 앱을 만들고 있습니다. 이 Redshift 데이터베이스에 쓴 사람들은 기괴한 선택을했습니다. 내가파이썬, 유니 코드 : 잘못된 형식의 문자열로 작업하기

u'Let\u2019s play! \\xe2\\x9a\\xbd\\xef\\xb8\\x8f' 

파이썬으로이납니다 psycopg2와

Let’s play! \xe2\x9a\xbd\xef\xb8\x8f 

나는대로이 렌더링하기로 해요 : 나는이 같은 문자열을 가지고 있다는 사실을 처리하는 방법을 알아 내려고 노력하고있어

놀자! ⚽️

이들은 빨간색 전환 테이블에 varchar(65535)으로 저장됩니다. 나는 pyscopg2를 사용하여 앱 백엔드 (Django 1.11, Python 2.7)에 끌어다 놓았다. 프런트 엔드에서 JavaScript로 렌더링됩니다.

모든 의견을 보내 주시면 감사하겠습니다. 해결책을 찾지 못했습니다.

+1

당신은 ([글자 깨짐]있어 HTTPS 아래

은 진수 이스케이프 시퀀스를 찾을 수와 UTF-8 디코딩 상당으로 대체하는 정규 표현식이다 : //en.wikipedia.org/wiki/Mojibake)를 데이터베이스에 저장하십시오. 그것은 인코딩을 혼합합니다. 결과를 반환 할 수있는 인코더를 찾을 수 없기 때문에 psycopg2에서 수행 한 결과를 어떻게 얻었는지 확신 할 수 없습니다. U + 2019 코드 포인트를 얻는 것은 Windows-125x 엔코더를 의미하지만, 그 중 아무 것도 오류없이 Python에서 UTF-8 나머지를 반환하지는 않습니다. 문자열의 올바른 UTF-8 인코딩은''\ xe2 \ x80 \ x99s를 재생하자! \ xe2 \ x9a \ xbd \ xef \ xb8 \ x8f "\ –

+0

와우, 당신은 psycopg2에서 얻는 것에 대해 옳습니다. 업데이트 된 질문. –

답변

1

인코딩이 혼합되어 있기 때문에 (Windows-1252 및 16 진수 UTF-8과 같은 모양)이 혼합이 일관되면 항목을 사후 처리 할 수 ​​있습니다.

import re 

esc = re.compile(r'(?:\\x[0-9a-f]{2})+') 

def fixer(m): 
    return m.group().encode('latin1').decode('unicode-escape').encode('latin1').decode('utf8') 

s = u'Let\u2019s play! \\xe2\\x9a\\xbd\\xef\\xb8\\x8f' 
f = esc.sub(fixer,s) 
print repr(f) 
print f 

출력 :

u'Let\u2019s play! \u26bd\ufe0f' 
Let’s play! ⚽️ 
+0

감사합니다. 이 대답을 수락하십시오. 왜 인코딩, 디코딩, 다시 인코딩 및 디코딩하는지 설명 할 수 있습니까? 나는 많은 유니 코드 솔루션의 일부로이를 보았고 그 이유에 대해서는 분명히 알지 못합니다. –

+1

@NathanHinchey 당신은 * 바이트로 인코딩 * 유니 코드로 * 디코딩 *. .encode ('latin1')'은 latin1 문자 집합이 유니 코드의 첫 번째 256 코드 점이기 때문에 U + 0000을 U + 00FF로 바이트 00-FF로 직접 변환하는 트릭입니다. 따라서 유니 코드 문자열에서 시작하여'unicode-escape' 코덱을 사용할 수 있도록 바이트로 바꿉니다. 결과는 다른 유니 코드 문자열이므로 바이트로 다시 인코딩하고 UTF8로 디코딩하십시오. –