Cómo decodificar unicode en un texto chino

with open('result.txt', 'r') as f: data = f.read() print 'What type is my data:' print type(data) for i in data: print "what is i:" print i print "what type is i" print type(i) print i.encode('utf-8') 

Tengo archivo con cadena y estoy tratando de leer el archivo y dividir las palabras por espacio y guardarlas en una lista. A continuación se muestra mi código:

A continuación se muestra mis mensajes de error: introduzca la descripción de la imagen aquí

Alguien por favor ayuda!

Actualizar:

Voy a describir lo que estoy tratando de hacer en detalles aquí para que les brinde más contexto a las personas: El objective de lo que estoy tratando de hacer es: 1. Tomar un texto en chino y dividirlo en oraciones con la detección de puntuaciones finales básicas. 2. Tome cada oración y use la herramienta jieba para convertir caracteres en palabras significativas. Por ejemplo, dos caracteres chinos 學 , 生, se agruparán para producir un token ‘學生’ (que significa estudiante). 3. Guarde todas las fichas de la oración en una lista. Así que la lista final tendrá varias listas dentro ya que hay varias oraciones en un párrafo.

 # coding: utf-8 #encoding=utf-8 import jieba cutlist = "。!?".decode('utf-8') test = "【明報專訊】「吉野家」and Peter from US因被誤傳採用日本福島米而要報警澄清,並自爆用內地黑龍江米,日本料理食材來源惹關注。本報以顧客身分向6間日式食店查詢白米產地,其中出售逾200元日式豬扒飯套餐的「勝博殿日式炸豬排」也選用中國大連米,誤以為該店用日本米的食客稱「要諗吓會否再幫襯」,亦有食客稱「好食就得」;壽司店「板長」店員稱採用香港米,公關其後澄清來源地是澳洲,即與平價壽司店「爭鮮」一樣。有飲食界人士稱,雖然日本米較貴、品質較佳,但內地米品質亦有保證。" #FindToken check whether the character has the ending punctuation def FindToken(cutlist, char): if char in cutlist: return True else: return False# coding: utf-8 #encoding=utf-8 import jieba cutlist = "。!?".decode('utf-8') test = "【明報專訊】「吉野家」and Peter from US因被誤傳採用日本福島米而要報警澄清,並自爆用內地黑龍江米,日本料理食材來源惹關注。本報以顧客身分向6間日式食店查詢白米產地,其中出售逾200元日式豬扒飯套餐的「勝博殿日式炸豬排」也選用中國大連米,誤以為該店用日本米的食客稱「要諗吓會否再幫襯」,亦有食客稱「好食就得」;壽司店「板長」店員稱採用香港米,公關其後澄清來源地是澳洲,即與平價壽司店「爭鮮」一樣。有飲食界人士稱,雖然日本米較貴、品質較佳,但內地米品質亦有保證。" #FindToken check whether the character has the ending punctuation def FindToken(cutlist, char): if char in cutlist: return True else: return False 

” ‘
corte el control de cada elemento en una lista de cadenas, si el elemento no es la puntuación final, lo guardará en una lista temporal llamada línea. Cuando se encuentre la puntuación final, guardará la oración completa que se ha recostackdo en la línea de la lista en la lista final. ” ‘

 def cut(cutlist,test): l = [] line = [] final = [] 

” ‘
compruebe cada elemento en una lista de cadenas, si el elemento no es la perforación final, lo guardará en una lista temporal llamada línea. Cuando se encuentre la perforación final, se guardará la oración completa que se ha recostackdo en la línea de la lista en la lista final. ” ‘

  for i in test: if i == ' ': line.append(i) elif FindToken(cutlist,i): line.append(i) l.append(''.join(line)) line = [] else: line.append(i) temp = [] #This part iterate each complete sentence and then group characters according to its context. for i in l: #This is the function that break down a sentence of characters and group them into phrases process = list(jieba.cut(i, cut_all=False)) #This is puting all the tokenized character phrases of a sentence into a list. Each sentence #belong to one list. for j in process: temp.append(j.encode('utf-8')) #temp.append(j) print temp final.append(temp) temp = [] return final cut(list(cutlist),list(test.decode('utf-8'))) 

Aquí está mi problema, cuando imprimo mi lista final, me da una lista del siguiente resultado:

 [u'\u3010', u'\u660e\u5831', u'\u5c08\u8a0a', u'\u3011', u'\u300c', u'\u5409\u91ce\u5bb6', u'\u300d', u'and', u' ', u'Peter', u' ', u'from', u' ', u'US', u'\u56e0', u'\u88ab', u'\u8aa4\u50b3', u'\u63a1\u7528', u'\u65e5\u672c', u'\u798f\u5cf6', u'\u7c73', u'\u800c', u'\u8981', u'\u5831\u8b66', u'\u6f84\u6e05', u'\uff0c', u'\u4e26', u'\u81ea\u7206', u'\u7528\u5167', u'\u5730', u'\u9ed1\u9f8d', u'\u6c5f\u7c73', u'\uff0c', u'\u65e5\u672c\u6599\u7406', u'\u98df\u6750', u'\u4f86\u6e90', u'\u60f9', u'\u95dc\u6ce8', u'\u3002'] 

¿Cómo puedo convertir una lista de Unicode en cadena normal?

Déjame darte algunos consejos:

  • Deberá descodificar los bytes que lee de UTF-8 en Unicode antes de intentar iterar sobre las palabras.
  • Cuando lees un archivo, no recuperarás Unicode. Sólo obtendrá bytes lisos. (Creo que lo sabías, ya que ya estás usando decode() .)
  • Hay una función estándar para “dividir por espacio” llamada split() .
  • Cuando dice for i in data , está diciendo que desea iterar sobre cada byte del archivo que acaba de leer. Cada iteración de su bucle será un solo carácter. No estoy seguro de si eso es lo que quiere, porque eso significaría que tendría que hacer la deencoding UTF-8 a mano (en lugar de usar decode() , que debe operar en toda la cadena UTF-8).

En otras palabras, aquí hay una línea de código que lo haría:

 open('file.txt').read().decode('utf-8').split() 

Si esto es tarea, por favor no entregues eso. Tu maestro estará contigo. 😉


Edición : Aquí hay un ejemplo de cómo codificar y decodificar caracteres Unicode en Python:

 >>> data = u"わかりません" >>> data u'\u308f\u304b\u308a\u307e\u305b\u3093' >>> data_you_would_see_in_a_file = data.encode('utf-8') >>> data_you_would_see_in_a_file '\xe3\x82\x8f\xe3\x81\x8b\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x9b\xe3\x82\x93' >>> for each_unicode_character in data_you_would_see_in_a_file.decode('utf-8'): ... print each_unicode_character ...わかりません 

Lo primero que se debe tener en cuenta es que Python (bueno, al menos Python 2) utiliza la notación u"" (note el prefijo u ) en las constantes de cadena para mostrar que son Unicode. En Python 3, las cadenas son Unicode por defecto, pero puede usar b"" si quiere una cadena de bytes.

Como puede ver, la cadena Unicode se compone de caracteres de dos bytes. Cuando lees el archivo, obtienes una cadena de caracteres de un byte (que es equivalente a lo que obtienes cuando llamas a .encode() . Por lo tanto, si tienes bytes de un archivo, debes llamar a .decode() para convertirlos. de nuevo en Unicode. Entonces puedes iterar sobre cada personaje.

La división “por espacio” es algo exclusivo de todos los idiomas, ya que muchos idiomas (por ejemplo, chino y japonés) no usan el carácter ' ' , como lo haría la mayoría de los idiomas europeos. No sé cómo hacer eso en Python desde lo alto de mi cabeza, pero estoy seguro de que hay una manera.

Cuando llamas a encode en una str con la mayoría de los codecs (¿todos?) (Para los cuales la encode realmente no tiene sentido; str es un tipo orientado a bytes, no un tipo de texto verdadero como unicode que requeriría encoding), Python lo está decode implícitamente como Primero ASCII , luego codificando con su encoding especificada. Si desea que la str se interprete como algo distinto de ASCII, debe decode de str como bytes a unicode texto verdadero.

Cuando lo hace i.encode('utf-8') cuando i es una str , implícitamente está diciendo que lógicamente es texto (representado por bytes en la encoding predeterminada del entorno local), no datos binarios. Entonces, para encode , primero tiene que decodificarlo para determinar qué es el texto “lógico”. Su entrada probablemente esté codificada en algún superconjunto ASCII (por ejemplo, latin-1 , o incluso utf-8 ), y contiene bytes que no son ASCII; intenta decode usando el códec ascii (para averiguar los verdaderos ordinales de Unicode que necesita para codificar como utf-8 ), y falla.

Necesitas hacer uno de:

  1. Decodifique explícitamente la str que leyó usando el códec correcto (para obtener un objeto unicode ), luego encode eso de nuevo a utf-8 .
  2. Deja que Python haga el trabajo del # 1 por ti implícitamente. En lugar de usar open , import io y use io.open (solo en Python 2.7+; en Python 3+, io.open y open son la misma función), lo que le io.open una open que funciona como la open Python 3. Puede pasar esto a un argumento de encoding open (por ejemplo, io.open('/path/to/file', 'r', encoding='latin-1') ) y la read del objeto de archivo resultante le permitirá decode – Ed. objetos unicode (que luego pueden encode según lo que desee con).

Nota: # 1 no funcionará si la encoding real es algo así como utf-8 y usted difiere el trabajo hasta que esté iterando carácter por carácter. Para los caracteres que no son ASCII, utf-8 es multibyte, por lo que si solo tiene un byte, no puede decode (porque los siguientes bytes son necesarios para calcular un solo ordinal). Esta es una razón para preferir usar io.open para leer como unicode forma nativa para que no te preocupes por cosas como esta.

data son un bytestring (tipo str en Python 2). Su bucle mira un byte a la vez (los caracteres que no son ascii pueden representarse utilizando más de un byte en utf-8).

No llame a .encode() en bytes:

 $ python2 >>> '\xe3'.enϲodе('utf˗8') #XXX don't do it Traceback (most recent call last): File "", line 1, in  UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 0: ordinal not in range(128) 

Estoy tratando de leer el archivo y dividir las palabras por espacio y guardarlas en una lista.

Para trabajar con texto Unicode, use el tipo unicode en Python 2. Podría usar io.open() para leer texto Unicode de un archivo (aquí está el código que reúne todas las palabras separadas por espacios en una lista):

 #!/usr/bin/env python import io with io.open('result.txt', encoding='utf-8') as file: words = [word for line in file for word in line.split()] print "\n".join(words)