2010-02-26 8 views
10

:) Ich habe versucht, mit w = Word (Ausdrucke), aber es funktioniert nicht. Wie soll ich die Spezifikation dafür geben? 'w' soll Hindi-Zeichen verarbeiten (UTF-8)Python - pyparsing Unicode-Zeichen

Der Code spezifiziert die Grammatik und parst entsprechend.

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

Wenn nur Englisch Zeichen ist es funktioniert so ist der Code korrekt für das ASCII-Format, aber der Code funktioniert nicht für das Unicode-Format.

meine ich, dass der Code funktioniert, wenn wir etwas von der Form 671.assess :: ahsaas haben :: 2

dh es Worte im Englisch-Format analysiert, aber ich bin nicht sicher, wie zu analysieren und dann drucke Zeichen im Unicode-Format. Ich brauche das für Englisch Hindi Wortausrichtung für den Zweck.

Der Python-Code sieht wie folgt aus:

# -*- 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() 
''' 

wenn ein Beispiel Eingabesatz für die Quelldatei ist:

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]#$% 

die ouptut würde wie folgt aussehen: -

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]#$% 

Ausgabe Erläuterung: - Dadurch wird eine bidirektionale Ausrichtung erreicht. Es bedeutet, dass das erste Wort des englischen "modernen" Karten auf das erste Wort von Hindi "AddhUnIk" und umgekehrt. Hier werden sogar Zeichen als Wörter genommen, die auch Bestandteil der bidirektionalen Abbildung sind. Wenn du also das Hindi WORT 'beobachtest'. hat eine Null-Ausrichtung und es steht nichts in Bezug auf den englischen Satz, da es keinen Punkt hat. Die dritte Zeile in der Ausgabe stellt im Grunde ein Trennzeichen dar, wenn wir für eine Anzahl von Sätzen arbeiten, für die Sie versuchen, bidirektionales Mapping zu erreichen.

Welche Änderung sollte ich machen, damit es funktioniert, wenn ich die Hindi-Sätze im Unicode (UTF-8) -Format habe.

+1

diese Frage Bitte bearbeiten und Verwendung der richtigen Formatierung machen, so dass die Frage lesbar . –

Antwort

6

Als allgemeine Regel gilt, tun nicht Prozess codiert bytestrings: sie in die richtige Unicode-Strings machen (durch ihre .decode Methode aufrufen) so bald wie möglich, tun alle Ihre Verarbeitung immer auf Unicode-Strings, dann, wenn Sie für E/A-Zwecke, .encode Sie zurück in was auch immer Byte-String-Codierung benötigen Sie.

Wenn Sie Literale reden, wie es Sie in Ihrem Code scheint, ist die „so bald wie möglich“ sofort: verwenden u'...' Ihre Literale auszudrücken. In einem allgemeineren Fall, in dem Sie I/O in codierter Form ausführen müssen, geschieht dies unmittelbar nach der Eingabe (genau wie unmittelbar vor der Ausgabe, wenn Sie die Ausgabe in einer bestimmten codierten Form durchführen müssen).

+0

Hallo Herr .. :) Vielen Dank für Ihre Antwort .. was auch immer Sie im zweiten Absatz gesagt haben, ist genau auf meinen Fall anwendbar .. Ich habe dieses Ding in der folgenden Zeile des Codes versucht: trans = u'Word (Ausdrucke) ' und ich konnte die gewünschte Ausgabe nicht erreichen. Könnten Sie mich bitte korrigieren, wenn ich die Änderung in der falschen Zeile vorgenommen habe, da nach dieser Änderung der Fehler 'Erwartetes Ausdrucken an dieser Position' in Bezug auf die Zeilen, die das Grammar definieren, kommt. – boddhisattva

+0

@mgj, weisen Sie trans-Zeichen kein Unicode-String-Literal zu, das macht keinen Sinn. Stellen Sie sicher, dass 'printables' ein Unicode-Objekt ist (** nicht ** eine utf8-codierte Byte-Zeichenfolge! - noch eine Byte-Zeichenfolge mit einer anderen Codierung!), Und verwenden Sie' trans = Word (Ausdrucke) '. Wenn Ihr _file_ utf-8-codiert oder mit einer anderen Kodierung kodiert ist, dekodieren Sie es mit 'codecs.open' aus dem' codecs'-Modul, _nicht_ dem eingebauten 'open', wie Sie es tun, so dass jeder' line' ist ein Unicode-Objekt, keine Byte-Zeichenfolge (in welcher Kodierung auch immer). –

21

Pyparsings printables behandelt nur Zeichenfolgen im ASCII-Zeichenbereich.Sie wollen Printables in der vollen Unicode-Bereich, wie folgt aus:

trans = Word(unicodePrintables) 

ich nicht in der Lage war, gegen Ihre Hindi zu testen:

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

Jetzt können Sie trans mit dieser vollständigeren Satz von Nicht-Leerzeichen definieren Test-String, aber ich denke, das wird den Trick machen.

(Wenn Sie Python 3 verwenden, dann gibt es keine separate unichr Funktion und kein xrange Generator, benutzen Sie einfach:

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

Vielen Dank für Ihre Antwort Sir .. :) – boddhisattva

+0

Diese Antwort ist längst veraltet: Unicode ist nicht mehr 16 Bit, und Schleifen ist alles überhaupt nicht performant. –

+2

@flyingsheep - guter Tipp, aktualisiert, um 'sys.maxunicode' anstelle einer fest codierten Konstante zu verwenden, so dass es mit Pythons' sys' Modul verfolgt wird. Wie beim Schleifen alles, dieses Bit läuft nur einmal, wenn zunächst einen Parser zu definieren, und wenn verwendet, um ein pyparsing "Word" zu erstellen, wird als Set() gespeichert, so Parse-Zeit Leistung ist immer noch ziemlich gut. – PaulMcG