Python - кодек, кодирующий ascii в unicode: ошибка - PullRequest
0 голосов
/ 15 февраля 2010

:) Я пытаюсь вернуться к процессу возврата транслитерации входного файла (в настоящее время на английском языке) к его первоначальному виду (на хинди)

Пример или часть входного файла выглядит следующим образом:

E-k- b-u-d-z*dhi-m-aan- p-ksii#

E-k- ghn-e- j-ngg-l- m-e-ng E-k- b-h-u-t- UUNNc-aa p-e-dr thaa#
U-s- k-ii p-t-z*t-o-ng s-e- l-d-ii shaakhaay-e-ng m-j-*zb-uut- b-aaj-u-O-ng k-ii t-r-h- pheil-ii h-u-II thiing#
w-n- h-NNs-o-ng k-aa E-k- jhu-nhz*D- I-s- p-e-dr p-r- n-i-w-aas- k-r-t-aa thaa#
w-e- s-b- y-h-aaNN s-u-r-ksi-t- the- AUr- b-dre- AAr-aam- s-e- r-h-t-e- the-#
U-n- m-e-ng s-e- E-k- p-ksii b-h-u-t- b-u-d-z*dhi-m-aan- thaa#
I-s- b-u-d-z*dhi-m-aan- p-ksii n-e- E-k- d-i-n- p-e-dr k-ii j-dr m-e-ng s-e- E-k- l-t-aa k-o- U-g-t-e- d-e-khaa# 
I-s- k-e- b-aar-e- m-e-ng U-s-n-e- d-uus-r-e- p-ksi-y-o-ng s-e- b-aat- k-ii#
"k-z*y-aa t-u-m-z*h-e-ng w-h- l-t-aa d-i-khaaII d-e-t-ii h-ei", U-s- n-e- U-n- s-e- p-uuchaa "t-u-m-z*h-e-ng I-s-e- n-Shz*T- k-r- d-e-n-aa c-aah-i-E-"#
"I-s-e- k-z*y-o-ng n-Shz*T- k-r- d-e-n-aa c-aah-i-E-?" h-NNs-o-ng n-e- AAshz*c-*ry- s-e- p-uuchaa "y-h- t-o- I-t-n-ii cho-T-ii s-e- h-ei#
h-m-e-ng y-h- k-z*y-aa h-aan-i- p-h-u-NNc-aa s-k-t-ii h-ei"#
"m-e-r-e- m-i-tro-ng," b-u-d-z*dhi-m-aan- p-ksii n-e- U-t-z*t-r- d-i-y-aa "w-h- cho-T-ii s-ii l-t-aa j-l-z*d-ii h-ii b-drii h-o- j-aay-e-g-ii#
y-h- h-m-aar-e- p-e-dr p-r- c-Dh*z k-r- U-s- s-e- l-i-p-T-t-ii j-aay-e-g-ii AUr- phi-r- m-o-T-ii AUr- m-j-*zb-uut- h-o- j-aay-e-g-ii"#
"t-o- k-z*y-aa h-u-AA"#

Его эквивалентное значение на английском языке:

A WISE OLD BIRD.

Deep in the forest stood a very tall tree.
Its leafy branches spread out like long arms.
This was the home of a flock of wild geese.
They were safe there.
One of the geese was a wild old bird.
One  day this wise old bird noticed  a small creeper growing at the foot of the tree.
He spoke to the other birds about it.
"Do you see that creeper ?" he said to them.
"You must destroy it."
"Why must we destroy it ?" asked the geese in surprise.
"It is so small.
What harm can it do?"
"My friends," replied the wise old bird, " that little creeper will soon grow.

Мой скрипт выглядит так:

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import sys
CODEC = 'utf-8'
input_file=sys.argv[1]
output_file=sys.argv[2]
list1=[]



f=open(input_file,'r')
f1 = open(output_file,'w')

english_hindi_dict={'A' : u'अ' ,  'AA' : u'आ ' , 'I' : u'इ' , 'II' : u'ई ' , 'U' : u'उ ' ,\
                'UU' : u'ऊ' , 'r' : u'ऋ' , 'E' : u'ए' , 'ai' : u'ऐ' , 'O' : u'ओ' , 'AU' : u'औ' ,\
                'k' : u'क' , 'kh' : u'ख' , 'g' : u'ग' , 'gh' : u'घ' , 'c' : u'च' , 'ch' : u'छ',\
                'j': u'ज' , 'jh' : u'झ' , 'tr' : u'त्र' , 'T' : u'ट'  , 'Th' : u'ठ' , 'D' : u'ड',\
                'dr' : u'ड' , 'Dh' : u'ढ' , 'Na' : u'ण' , 'th' : u'त' ,  'tha' : u'थ',\
                'd' : u'द' , 'dh': u'ध' , 'n' : u'न' , 'p' : u'प' , 'ph' : u'फ' ,\
                'b' : u'ब' , 'bh' : u'भ' , 'm' : u'म' , 'y' : u'य' , 'r' : u'र' , 'l' : u'ल' ,\
                'w' : u'व' , 'sh' : u'श' , 'sha' : u'ष', 's' : u'स' , 'h' : u'ह' , 'ks' : u'क्ष' ,\
                'i' : u'ि' , 'ii' : u'ी' , 'u' : u'ु' , 'uu' : u'ू' , 'e' : u'े' ,\
                'aa' : u'ै' , 'o' : u'ो' , 'AU' : u'ौ' ,'H' : u'्' ,'mn' : u'ं' ,\
                'NN' : u'ँ' , 'AW' : u'ॅ' , 'rr' : u'ृ' , '4' : u'४' , '6': u'६'  , '8' : u'८',\
                '2' : u'२' , '5' : u'५' , '3' : u'३' , '7' : u'७' , '9' : u'९' , '1' : u'१'}
for line in f:
      #line=line.strip() to remove a line from its newline character....  
      #line=line.rstrip('.')   
      line=line.replace('-','')
      line=line.replace('#','|') # i am using the or symbol for poornviram
      #line=line.replace('।','')
      #line = line.lower()
for word in line:
    for ch in word:
        if (ch in english_hindi_dict) :
            translatedToken = english_hindi_dict[ch]
        else :
                translatedToken = ch

#{ translatedToken = english_hindi_dict[ch] }

#for ch in line:
    f1.write(translatedToken)
    #print translatedToken
    #line = line.replace( char,english_hindi_dict[char] )   
      #list1.append(line)
f.close()

f1.write(' '.join(list1))

f1.close()

ошибка, которую я получаю:

python transliterate_eh_nw.py Hstory.txt op1.txt
Traceback (most recent call last):
  File "transliterate_eh_nw.py", line 43, in <module>
    f1.write(translatedToken)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u092f' in position 0: ordinal not in range(128)

Подскажите, пожалуйста, как мне справиться с этой ошибкой. Спасибо ..:)

Ответы [ 3 ]

4 голосов
/ 16 февраля 2010

У вас есть несколько проблем, отличных от той, о которой вы спрашивали.

(1) Концептуальная проблема: "Ek-budz * dhi-m-aan- p-ksii #" равна не"английский".Это язык хинди, написанный на ASCII с использованием некоторой схемы латинизации.Это похоже на ITRAN, но ITRAN не имеет AA и A, у него есть только aa и a.У схемы есть имя?Можете ли вы предоставить URL?Ваш объект лучше описать как «транслитерацию некоторого текста на хинди из безымянной латинизации в сценарий деванагари».

(2) Отображение результата перевода вашего текста с хинди на английский («Мудрое старое животное» и т. Д.)только умеренно полезный.Ожидаемый вывод Деванагари был бы лучшей идеей.

(3) Как отметил @ kaiser.se, словарь транслитерации имеет многобайтовые (до 3 байтов!) Ключи, некоторые из которых являются префиксами других,Предположительно AA должно быть распознано в приоритетном порядке до A, gh должно быть распознано до g и т. Д. Итерации по элементам словаря происходят в порядке, который предсказуем, но для ваших целей должен рассматриваться как случайный,В следующем коде я отдал приоритет более длинным «ключам».

(4) Либо в словаре отсутствуют некоторые буквенные ключи (S tz), либо правила транслитерации сложнее, чем у любого из нас.до сих пор догадывался

(5) Значение символов # * и - не на 100% очевидно.Из вашего входного текста следует, что z и * появляются только в комбинации как z *

(6) Было бы неплохо, если бы вы объяснили интерпретацию, например, shaakhaay-e-ng ... начинается ли она с sh затем aa или оно начинается с sha, затем a?Каковы правила?

Ответ на проблему, о которой вы спрашивали, конечно же, так как несколько других указали, что вам необходимо кодировать вывод Unicode, используя кодировку, поддерживаемую вашим устройством отображения, например UTF-8.

Вот некоторый код:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

input_data = """
E-k- b-u-d-z*dhi-m-aan- p-ksii#

E-k- ghn-e- j-ngg-l- m-e-ng E-k- b-h-u-t- UUNNc-aa p-e-dr thaa#
[snip]
"t-o- k-z*y-aa h-u-AA"#
"""

roman_devanagari_dict={'A' : u'अ' ,  'AA' : u'आ ' , 'I' : u'इ' , 'II' : u'ई ' , 'U' : u'उ ' ,\
[snip]
            '2' : u'२' , '5' : u'५' , '3' : u'३' , '7' : u'७' , '9' : u'९' , '1' : u'१'}

#Presuming we need to do the 3-letter cases then the 2-letter then the 1-letter
replacements = [(-len(k), unicode(k), v) for k, v in roman_devanagari_dict.items()]
replacements.sort()

data = input_data.decode('ascii')

for _junk, from_text, to_text in replacements:
    data = data.replace(from_text, to_text)

# Presuming the '-' are inter-character markers, delete them last, not first
data = data.replace(u'-', '')
data = data.replace(u'#', '')
print "untransliterated:", set(c for c in data if 0x20 < ord(c) < 0x7f)

BOM = u'\ufeff'
outf = open('devanagari.txt', 'w')
outf.write(BOM.encode('utf8')) # for the benefit of clueless Windows s/w
outf.write(data.encode('utf8'))
outf.close()

Вывод:

* बुद z * बहु पक्षी

एक घने जनगगल मेनग एक बहु बहु बहु z tz t ोनग से ष ष 10 10 z बू बैजुओनग मज रह झुनह मज तीनग वन कै झुनह * 10 10 10 ड 37 37 37 37 37 सुरक्षि सुरक्षि सुरक्षि सुरक्षि रह रह रह रह रह रह ेबुद z धिमैन थ a इस बुद z धिमैन पक्षक ने एक दिन की जड मेनग से से ल ल ल ल ग ग ग ग ग ग इस इस की कीउपूछै "t ुम z हेनग इसे न S ह z ट कर देनै चैहिए" "इसे क z योनग न S ह z ट कर देनै चैहिए?"श ने आ श z रय से पूछै "ो t ो इ t नी छोटी क हेि हमेनग क क z यै हैनि पहुँचै सक t ी हेि" "मेरे मित्रोनग," बुद z धिमैन पक्षी ने उ tz t दियै दियै वह वह ल t जल z 52 ही बडी हो यह हमैरे हमैरे चढ चढ 10 10 52 52 52 52 52 52 लिपट 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 54 54 54 54 54 1054हुआ "

, который имеет только несколько узнаваемых слов при отправке через Google Translate.

Обновление после более тщательного изучения таблицы транслитерации:

  • Три записи (AA, II и U) имеют пробел после эквивалента Деванагари.Возможно, пробелы следует удалить.

  • Общий шаблон для согласных выглядит следующим образом:

Письмо DEVANAGARI XA представлено как x
Письмо DEVANAGARI XXA представлено как X
Письмо DEVANAGARI XHA представлено как xh
Письмо DEVANAGARI XXHA представлено как Xh

Однако 3 записи нарушают шаблон:
SSA -> sha, но шаблон говоритS
TA -> th, но шаблон говорит, что t
THA -> tha, но шаблон говорит, что *

Примечание: изменение вышеуказанных 3-х записей не давало моему коду жаловаться, что S и t были оставлены неизменными при транслитерацииВаш образец текста и удалил, казалось бы, аномальные записи sha и tha.

  • Записи (D и dr) отображаются на один и тот же символ DEVANAGARI LETTER DDA.D - ожидаемая запись для этого символа;возможно, доктор должен быть сделанв другом месте.

  • Нет записи для Письма DEVANAGARI NGA (U + 0919); возможно, он должен быть закодирован как ng - в образце текста есть несколько слов, оканчивающихся на ng.

  • Имеют ли вхождения в строку «z *» в тексте образца какое-либо отношение к DEVANAGARI LETTER ZA (U + 095B)?

1 голос
/ 15 февраля 2010

Вы уверены, что хотите удалить все дефисы (-)? Глядя на ваш входной файл, кажется, что все замены представляют собой двух- или трехсимвольные коды, такие как u'I - ': u' इ '. Если это так, вы можете сделать что-то вроде ниже, но убедитесь, что вы используете строки Unicode для всех ваших ключей и значений в словаре:

import codecs

# read the whole file at once
f = codecs.open(input_file,'r','ascii')
data = f.read()
f.close()

# perform all the replacements
for k,v in english_hindi_dict.items():
    data = data.replace(k,v)

# write the whole file result
f = codecs.open(output_file,'w',CODEC)
f.write(data)
f.close()

Следуя этой теории, я получил следующий результат, который выглядит как переводы, такие как 'z *', 't-', 'ng' и 'ei', отсутствуют в словаре. Я не читаю хинди, но Google Translate предложил некоторые из английских слов в вашем переводе, поэтому я думаю, что я на правильном пути.

-z*धिमैन पक्षी

एक घने जngगल मेng एक बहुt- ऊँचै पेड तै
उस की पt-z*t-ोng से लदी शैखैयेng मज*zबूt- बैजुओng की t-रह फeiली हुई तीng
वन हँसोng कै एक झुnhz*ड इस पेड पर निवैस करt-ै तै
वे सब यहैँ सुरक्षिt- ते ौर बडे आरैम से रहt-े ते
उन मेng से एक पक्षी बहुt- बुदz*धिमैन तै
इस बुदz*धिमैन पक्षी ने एक दिन पेड की जड मेng से एक लt-ै को उगt-े देखै 
इस के बैरे मेng उसने दूसरे पक्षियोng से बैt- की
"कz*यै t-ुमz*हेng वह लt-ै दिखैई देt-ी हei", उस ने उन से पूछै "t-ुमz*हेng इसे नShz*ट कर देनै चैहिए"
"इसे कz*योng नShz*ट कर देनै चैहिए?" हँसोng ने आशz*च*rय से पूछै "यह t-ो इt-नी छोटी से हei
हमेng यह कz*यै हैनि पहुँचै सकt-ी हei"
"मेरे मित्रोng," बुदz*धिमैन पक्षी ने उt-z*t-र दियै "वह छोटी सी लt-ै जलz*दी ही बडी हो जैयेगी
यह हमैरे पेड पर चढ*z कर उस से लिपटt-ी जैयेगी ौर फिर मोटी ौर मज*zबूt- हो जैयेगी"
"t-ो कz*यै हुआ"
1 голос
/ 15 февраля 2010

f1.write ('' .join (list1))

list1, на данный момент, содержит строки Unicode. Вы не можете писать Unicode напрямую в файл, это байтовый интерфейс. Вы должны либо явно кодировать его (' '.join(list1).encode('utf-8')), либо, как предлагает Игнасио, использовать оболочку codecs для неявного кодирования строк Unicode, которые вы отправляете в него. В данный момент вы определяете переменную CODEC, но ничего с ней не делаете.

...