代码之家  ›  专栏  ›  技术社区  ›  boddhisattva

python-codec将ascii编码为unicode:错误

  •  0
  • boddhisattva  · 技术社区  · 15 年前

    :)我正在尝试将输入文件(当前为英语)的音译转换回其原始形式(印地语)的过程。

    输入文件的一个示例或一部分如下:

    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 回复  |  直到 15 年前
        1
  •  4
  •   John Machin Santi    15 年前

    除了你问的问题,你还有一些问题。

    (1)概念问题:“e-k-b-u-d-z*dhi-m-aan-p-ksii”是 “英语”。它是一种印地语,使用某种罗马化方案以ASCII码书写。看起来像iTrans,但iTrans没有AA和A,只有AA和A。这个计划有名字吗?你能提供一个网址吗?您的对象更好地描述为“将一些印地语文本从未命名的罗马化翻译为天成文书(devanagari)脚本”。

    (2)显示将文本从印地语翻译成英语的结果(“聪明的老鸟”等)只是中等程度的有用。预计天成文书输出将是一个更好的主意。

    (3)如@kaiser.se所述,音译字典有多个字节(最多3个字节!)键,其中一些是其他键的前缀。想必 AA 必须优先考虑 A , gh 之前必须确认 g 等等。对字典中的项进行迭代的顺序是可预测的,但出于您的目的,应该将其视为随机的。在下面的代码中,我优先使用更长的“键”。

    (4)要么字典缺少一些字母键(a s t z),要么音译规则比我们迄今所猜测的更复杂。

    (5)字符*和-的含义并非100%明显。从输入文本中,Z和*仅以Z的形式组合出现。*

    (6)如果你解释了例如 shaakhaay-e-ng …是从一开始吗 sh 然后 aa 还是从一开始 sha 然后 a ?规则是什么?

    当然,对于您询问的问题的答案是,正如其他一些人指出的那样,您需要使用显示设备(如UTF-8)支持的编码对Unicode输出进行编码。

    下面是一些代码:

    #!/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()
    

    输出:

    _

    _ 224; 224; 224; \ 224; \224; \224; 224; A _ _ _ _ _ tz T__ _ Z_ 224; 224; 224; \ \ 224__ ___________________ _·_·_·_·_·_·_·_·_·_·_·_·_·_·_·_·_·_·_·_·_·T_·_·A वे सब यहैँ सुरक्षिt ते ौर बडे आ रैम से रहtे ते ____________________ _¨_¨_¨_¨_¨_¨A _______ धिमैन पक्षी ने एक दिन पेड की जड मेनग से एक लtै को उ गtे देखै इस के बैरे मेनग उ सने दूसरे पक्षियोनग से बैt की “_ Z _ _ t_ z हेनग वह लtै दिखैई देtी हेि", उ स ने उ न से पूछै "tुमz _____________垎 _ _ _ _ _ _ _ _ _ _” “_ _ _ _ Z ____ _¨s_垎 _ _ _ _ _ _ _ _ _ _??______________ 阿尔法 _ 224; 224; 224;? _____224;_224;_______ _________________ “_?_?_?_?_?_?_?_?_?_?_?_?_?_?_?_?_?_?_?_?Z _¨_¨_¨_¨_¨_¨_¨_¨_¨_¨_¨_¨_¨_ tz T________________ _______________ _______ ________ _ 224; 224; 224; 224; \224; 224; Z_ T_ _ _ _ _” “T Z “舒适”

    在谷歌翻译的过程中,只有几个可识别的词。

    更新 仔细检查音译表后:

    • 其中三个条目(a a、ii和u)在天成文书(梵文)之后有一个空格。也许这些空间应该被移除。

    • 辅音的一般模式是:

    天成文书(梵文)字母Xa由x表示
    天成文书(梵文)字母XXa由x表示
    天成文书(梵文)字母Xha由Xh表示
    天成文书(梵文)字母XXha由xh表示

    但是有3个条目破坏了模式:
    SSA->sha,但模式显示
    但是模式上说
    但是模式说

    注意:更改上面的3个条目使我的代码不再抱怨在翻译示例文本时s和t保持不变,并删除了看起来异常的sha和tha条目。

    • 条目(d和dr)映射到同一个字符,天成文书(梵文)字母dda。d是该字符的预期条目;也许应该将dr映射到其他地方。

    • 天成文书(梵文)字母Nga(U+0919)没有条目;也许它应该编码为ng——在示例文本中有几个单词以ng结尾。

    • 示例文本中出现的“z*”未加引号是否与天成文书(梵文)字母Za(U+095b)有关?

        2
  •  1
  •   bobince    15 年前

    f1.写入(“.”join(list1))

    list1 此时,包含Unicode字符串。不能将Unicode直接写入文件,它是一个字节接口。你要么显式编码它 (' '.join(list1).encode('utf-8')) 或者,正如伊格纳西奥建议的,使用 codecs 包装器隐式编码发送给它的Unicode字符串。现在您正在定义一个变量 CODEC 但不做任何事情。

        3
  •  1
  •   Mark Tolonen    15 年前

    确实要删除所有连字符(-)吗?查看您的输入文件,看起来所有替换的内容都是两个或三个字符的代码,例如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”等翻译。我不读印地语,但谷歌翻译公司在你的翻译中发现了一些英文单词,所以我认为我走对了。

    -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*यै हुआ"
    
    推荐文章