2012-02-10 22 views
18

'ö', 'ü', vb. Gibi karakterler içeren utf-8 kodlaması kullanan metin dosyalarım var. Bu dosyaları metin formunu ayrıştırmak istiyorum ancak belirteci alamıyorum. düzgün çalış.nltk kullanarak unicode kullanarak hizalama

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) 

Çıktı:

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) 

çıktı: [u'\ufeffm\xfcsli', u'p\xf6\xf6k', u'r\xe4\xe4k']

yoktur [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 iyi yapmak gibi görünüyor ben standart nltk dizgeciklerini kullanırsanız yine İlk belirteçten önce '\ ufeff' anlayamadım (onu kaldıramıyorum). Neyi yanlış yapıyorum? Çok takdir edilmesine yardımcı olun.

cevap

19

O \uFEFF karakter dosyadan okunan içeriğin bir parçası olduğunu daha olasıdır. Tokmaklayıcı tarafından takıldığından şüpheliyim. Bir dosyanın başında \uFEFF, Byte Order Mark kullanımdan kaldırılmış bir formudur. Başka bir yerde görünürse, zero width non-break space olarak kabul edilir.

Dosya Microsoft Not Defteri ile yazılmış mıydı? the codecs module docs Gönderen:

UTF-8 kodlama tespit edilebileceği ile güvenilirliğini artırmak için, Microsoft UTF-8 bir varyantını icat (yani Python 2.5 görüşmeleri "utf-8-sig") onun Not Defteri programı için: Unicode karakterlerinden herhangi biri dosyaya yazılmadan önce, UTF-8 kodlu bir BOM (bayt dizisi gibi görünen: 0xef, 0xbb, 0xbf) yazılır.

yerine codecs.open() kullanarak dosyanızı okumaya çalışın. BOM'u tüketen "utf-8-sig" kodlamasına dikkat edin.

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

Deney:

>>> 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

Teşekkürler. Kodunuz hileyi kaldırıyor \ uFEFF – root

+0

@ user1199589 Rica ederim. Yardımcı olduğuma sevindim. –

+0

Bana da yardım etti. Çok teşekkürler! – Pitarou

4

UFEE kodu "SIFIR Genişlik Bölünmez UZAY" karakteridir ve bu re modülü tarafından bir alan olarak düşünmüyoruz, bu yüzden bayraklar unicode ile normal ifadeler r'\w+|[^\w\s]+' kullanmak ve dotall PunktWordTokenizer() bir kelime olarak bu karakteri tanımak . el karakteri kaldırmak istemiyorsanız, aşağıdaki dizgeciklerini kullanabilirsiniz:

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

Sen tokenizers nltk için unicode dizeleri geçiyoruz emin olmalısınız. Sonunda her iki belirteci ile dize aşağıdaki özdeşleştirmeleri olsun:

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']