2010-02-26 19 views
10

:) Próbowałem używać w = Word (printables), ale to nie działa. Jak powinienem podać specyfikację? "w" służy do przetwarzania znaków hindi (UTF-8)Python - pyparsing znaków unicode

Kod określa gramatykę i odpowiednio analizuje.

671.assess :: अहसास ::2 
x=number + "." + src + "::" + w + "::" + number + "." + number 

Jeśli istnieje tylko znaki języka angielskiego to działa tak, że kod jest prawidłowy dla formacie ASCII, ale kod nie działa w formacie Unicode.

To znaczy, że kod działa, gdy mamy coś formularza 671.assess :: ahsaas :: 2

czyli analizuje słowa w angielskim formacie, ale nie jestem pewien, jak analizować, a następnie drukuj znaki w formacie Unicode. Potrzebuję tego do celów wyrównania angielskich słów w języku hindi.

Kod pyton wygląda następująco:

# -*- coding: utf-8 -*- 
from pyparsing import Literal, Word, Optional, nums, alphas, ZeroOrMore, printables , Group , alphas8bit , 
# grammar 
src = Word(printables) 
trans = Word(printables) 
number = Word(nums) 
x=number + "." + src + "::" + trans + "::" + number + "." + number 
#parsing for eng-dict 
efiledata = open('b1aop_or_not_word.txt').read() 
eresults = x.parseString(efiledata) 
edict1 = {} 
edict2 = {} 
counter=0 
xx=list() 
for result in eresults: 
    trans=""#translation string 
    ew=""#english word 
    xx=result[0] 
    ew=xx[2] 
    trans=xx[4] 
    edict1 = { ew:trans } 
    edict2.update(edict1) 
print len(edict2) #no of entries in the english dictionary 
print "edict2 has been created" 
print "english dictionary" , edict2 

#parsing for hin-dict 
hfiledata = open('b1aop_or_not_word.txt').read() 
hresults = x.scanString(hfiledata) 
hdict1 = {} 
hdict2 = {} 
counter=0 
for result in hresults: 
    trans=""#translation string 
    hw=""#hin word 
    xx=result[0] 
    hw=xx[2] 
    trans=xx[4] 
    #print trans 
    hdict1 = { trans:hw } 
    hdict2.update(hdict1) 

print len(hdict2) #no of entries in the hindi dictionary 
print"hdict2 has been created" 
print "hindi dictionary" , hdict2 
''' 
####################################################################################################################### 

def translate(d, ow, hinlist): 
    if ow in d.keys():#ow=old word d=dict 
    print ow , "exists in the dictionary keys" 
     transes = d[ow] 
    transes = transes.split() 
     print "possible transes for" , ow , " = ", transes 
     for word in transes: 
      if word in hinlist: 
     print "trans for" , ow , " = ", word 
       return word 
     return None 
    else: 
     print ow , "absent" 
     return None 

f = open('bidir','w') 
#lines = ["'\ 
#5# 10 # and better performance in business in turn benefits consumers . # 0 0 0 0 0 0 0 0 0 0 \ 
#5# 11 # vHyaapaar mEmn bEhtr kaam upbhOkHtaaomn kE lIe laabhpHrdd hOtaa hAI . # 0 0 0 0 0 0 0 0 0 0 0 \ 
#'"] 
data=open('bi_full_2','rb').read() 
lines = data.split('[email protected]#$%') 
loc=0 
for line in lines: 
    eng, hin = [subline.split(' # ') 
       for subline in line.strip('\n').split('\n')] 

    for transdict, source, dest in [(edict2, eng, hin), 
            (hdict2, hin, eng)]: 
     sourcethings = source[2].split() 
     for word in source[1].split(): 
      tl = dest[1].split() 
      otherword = translate(transdict, word, tl) 
      loc = source[1].split().index(word) 
      if otherword is not None: 
       otherword = otherword.strip() 
       print word, ' <-> ', otherword, 'meaning=good' 
       if otherword in dest[1].split(): 
        print word, ' <-> ', otherword, 'trans=good' 
        sourcethings[loc] = str(
         dest[1].split().index(otherword) + 1) 

     source[2] = ' '.join(sourcethings) 

    eng = ' # '.join(eng) 
    hin = ' # '.join(hin) 
    f.write(eng+'\n'+hin+'\n\n\n') 
f.close() 
''' 

jeśli przykładem zdanie wejście do pliku źródłowego jest:

1# 5 # modern markets : confident consumers # 0 0 0 0 0 
1# 6 # AddhUnIk baajaar : AshHvsHt upbhOkHtaa . # 0 0 0 0 0 0 
[email protected]#$% 

ouptut będzie wyglądać następująco: -

1# 5 # modern markets : confident consumers # 1 2 3 4 5 
1# 6 # AddhUnIk baajaar : AshHvsHt upbhOkHtaa . # 1 2 3 4 5 0 
[email protected]#$% 

Wyjście Objaśnienie: - Zapewnia to dwukierunkowe wyrównanie. Oznacza to pierwsze słowo z angielskich "nowoczesnych" map do pierwszego słowa hindi "AddhUnIk" i na odwrót. Tutaj nawet postacie są traktowane jako słowa, ponieważ są one również integralną częścią mapowania dwukierunkowego. Jeśli więc zaobserwujesz hinduistyczne SŁOWO ". ma zerowy układ i nic nie odwzorowuje w odniesieniu do zdania angielskiego, ponieważ nie ma pełnego zatrzymania. Trzecia linia na wyjściu generalnie reprezentuje ogranicznik, gdy pracujemy dla wielu zdań, dla których próbujesz osiągnąć odwzorowanie dwukierunkowe.

Jakie zmiany należy wprowadzić, aby działały, jeśli mam zdania hindi w formacie Unicode (UTF-8).

+1

Proszę edytować to pytanie i skorzystać z poprawnym formatowaniem tak, że pytanie jest czytelny –

Odpowiedz

6

Zgodnie z ogólną zasadą, zrobić nie procesowe zakodowane bytestrings: uczynić je do odpowiednich ciągów Unicode (nazywając ich metoda .decode) tak szybko, jak to możliwe, zrobić wszystkie swoje przetwarzania zawsze na Unicode, a następnie, jeśli masz do celów I/O, .encode je z powrotem do dowolnego kodującego, czego potrzebujesz.

Jeśli mówisz literałów, jak się wydaje, jesteś w kodzie, „jak najszybciej” jest naraz: użyj u'...' aby wyrazić swoje literałów. W bardziej ogólnym przypadku, gdy jesteś zmuszony do wykonania I/O w postaci zakodowanej, jest to natychmiast po wprowadzeniu (tak jak bezpośrednio przed wyjściem, jeśli musisz wykonać wyjście w określonej zakodowanej formie).

+0

Witam Panie .. Dziękuję za odpowiedź .. cokolwiek powiedzieliście w 2. paragrafie jest dokładnie stosowane w moim przypadku. Próbowałem tego w następującej linii kodu: trans = u'Word (printables) " i nie mogłem osiągnąć pożądanej wydajności. Czy możesz mnie poprawić, jeśli dokonałem modyfikacji w niewłaściwym wierszu, ponieważ po wprowadzeniu tej zmiany nadchodzi błąd "Oczekiwanie na wydruki w tej pozycji" w odniesieniu do linii, które definiują gramogram. – boddhisattva

+0

@mgj, nie przypisuj literału napisu unicode do 'trans', co nie ma sensu. Po prostu upewnij się, że 'printables' jest obiektem unicode (** not ** ut kodowanym utf8 ciągiem bajtów! - ani ciągiem bajtów z żadnym innym kodowaniem!) I użyj' trans = Word (printables) '. Jeśli twój _plik_ jest zakodowany za pomocą UTF-8 lub zakodowany za pomocą jakiegokolwiek innego kodowania, dekoduj go, używając 'codecs.open' z modułu' codecs', _nie_ wbudowanego 'otwartego' tak jak to robisz, aby każdy z nich' line' jest obiektem unicode, a nie ciągiem bajtowym (niezależnie od kodowania). –

21

Pyparsing's printables obsługuje wyłącznie ciągi znaków w zakresie ASCII.Chcesz printables w pełnym zakresie Unicode, tak:

unicodePrintables = u''.join(unichr(c) for c in xrange(sys.maxunicode) 
             if not unichr(c).isspace()) 

Teraz można zdefiniować trans użyciu tej bardziej kompletny zestaw znaków non-space:

trans = Word(unicodePrintables) 

byłem w stanie przetestować przeciw Hindi ciąg testowy, ale myślę, że to wystarczy.

(Jeśli używasz Python 3, to nie ma oddzielnego funkcja unichr, a nie generator XRange, wystarczy użyć:

unicodePrintables = ''.join(chr(c) for c in range(sys.maxunicode) 
             if not chr(c).isspace()) 
+0

Dziękuję za odpowiedź sir .. :) – boddhisattva

+0

ta odpowiedź jest już dawno przestarzała: unicode nie jest już 16-bitowy, a zapętlanie wszystkiego w ogóle nie działa. –

+2

@flyingsheep - dobra wskazówka, zaktualizowana do użycia 'sys.maxunicode' zamiast stałej stałej, więc będzie śledzić za pomocą modułu' sys' Pythona. Co do zapętlenia wszystkiego, ten bit uruchamia się tylko raz, początkowo definiując parser, a kiedy jest używany do tworzenia "Worda" pypars, zostaje zapisany jako set(), więc wydajność parsowania jest wciąż całkiem dobra. – PaulMcG