2012-02-10 16 views
18

Tengo archivos de texto que usan codificación utf-8 que contienen caracteres como 'ö', 'ü', etc. Me gustaría analizar el texto de estos archivos, pero no puedo obtener el tokenizer para funcionar correctamente. Si uso tokenizer NLTK estándar:Tokenizing unicode usando nltk

f = open('C:\Python26\text.txt', 'r') # text = 'müsli pöök rääk' 
text = f.read() 
f.close 
items = text.decode('utf8') 
a = nltk.word_tokenize(items) 

Salida: [u'\ufeff', u'm', u'\xfc', u'sli', u'p', u'\xf6', u'\xf6', u'k', u'r', u'\xe4', u'\xe4', u'k']

Punkt tokenizer parece hacer mejor:

f = open('C:\Python26\text.txt', 'r') # text = 'müsli pöök rääk' 
text = f.read() 
f.close 
items = text.decode('utf8') 
a = PunktWordTokenizer().tokenize(items) 

de salida: [u'\ufeffm\xfcsli', u'p\xf6\xf6k', u'r\xe4\xe4k']

Hay todavía '\ uffff' antes del primer token que no puedo descifrar (no es que no pueda eliminarlo). ¿Qué estoy haciendo mal? Ayuda muy apreciada.

Respuesta

19

Es más probable que el \uFEFF char es parte del contenido leído del archivo. Dudo que haya sido insertado por el tokeniser. \uFEFF al comienzo de un archivo es una forma obsoleta de Byte Order Mark. Si aparece en cualquier otro lugar, se trata como zero width non-break space.

¿El archivo fue escrito por el Bloc de notas de Microsoft? De the codecs module docs:

Para aumentar la fiabilidad con la que se puede detectar una codificación UTF-8, Microsoft inventó una variante de UTF-8 (que Python 2.5 llamadas "UTF-8-sig") para su programa Bloc de notas: Antes de escribir cualquiera de los caracteres Unicode en el archivo, se escribe una BOM codificada en UTF-8 (que se ve así como una secuencia de bytes: 0xef, 0xbb, 0xbf).

Intente leer su archivo usando codecs.open() en su lugar. Tenga en cuenta la codificación "utf-8-sig" que consume la lista de materiales.

import codecs 
f = codecs.open('C:\Python26\text.txt', 'r', 'utf-8-sig') 
text = f.read() 
a = nltk.word_tokenize(text) 

Experimento:

>>> open("x.txt", "r").read().decode("utf-8") 
u'\ufeffm\xfcsli' 
>>> import codecs 
>>> codecs.open("x.txt", "r", "utf-8-sig").read() 
u'm\xfcsli' 
>>> 
+0

Gracias. Su código elimina el truco \ uFEFF – root

+0

@ user1199589 De nada. Me alegro de poder ayudar. –

+0

me ayudó a salir también. ¡Muchas gracias! – Pitarou

4

el código UFEE es un personaje "CERO ANCHO NO-BREAK SPACE" y esto no se considera como un espacio por el módulo re, por lo que el PunktWordTokenizer() que utilizan la expresión regular r'\w+|[^\w\s]+' con Unicode y dotall banderas reconocer este carácter como una palabra . Si no desea eliminar el carácter manualmente, puede utilizar el siguiente tokenizer:

nltk.RegexpTokenizer(u'\w+|[^\w\s\ufeff]+') 
12

Usted debe asegurarse de que estás pasando cadenas Unicode a NLTK tokenizers. Obtengo las siguientes identificaciones idénticas de su cadena con ambos tokenizadores en mi extremo:

import nltk 
nltk.wordpunct_tokenize('müsli pöök rääk'.decode('utf8')) 
# output : [u'm\xfcsli', u'p\xf6\xf6k', u'r\xe4\xe4k'] 

nltk.word_tokenize('müsli pöök rääk'.decode('utf8')) 
# output: [u'm\xfcsli', u'p\xf6\xf6k', u'r\xe4\xe4k'] 
Cuestiones relacionadas