2010-02-26 4 views
10

:) J'essayé d'utiliser w = Word (printables), mais il ne fonctionne pas. Comment dois-je donner les spécifications pour cela. 'W' est destiné à traiter des caractères Hindi (UTF-8)Python - caractères unicode pyparsing

Le code spécifie la grammaire et analyse en conséquence.

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

S'il n'y a que des caractères anglais, il travaille de sorte que le code est correct pour le format ascii mais le code ne fonctionne pas pour le format unicode.

Je veux dire que le code fonctionne quand nous avons quelque chose de la forme 671.assess :: ahsaas :: 2

-à-dire qu'il parse mots au format anglais, mais je ne suis pas sûr de savoir comment analyser et caractères d'impression au format Unicode. J'ai besoin de cela pour l'alignement du mot anglais hindi à des fins.

Le code python ressemble à ceci:

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

si une phrase d'entrée d'exemple pour le fichier source est:

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

le ouptut ressemblerait à ceci: -

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

Explication de sortie: - Ceci permet d'obtenir un alignement bidirectionnel. Cela signifie que le premier mot de cartes « modernes » anglais au premier mot de « AddhUnIk hindi » et vice-versa. Ici, même les caractères sont considérés comme des mots, car ils font également partie intégrante de la cartographie bidirectionnelle. Ainsi, si vous observez le mot hindi '.' a un alignement nul et il ne correspond à rien par rapport à la phrase anglaise, car il n'y a pas d'arrêt complet. La 3ème ligne int la sortie représente essentiellement un séparateur quand nous travaillons pour un certain nombre de phrases pour lesquelles vous essayez de réaliser la cartographie bidirectionnelle.

Quelle modification devrais-je faire pour que cela fonctionne si le je les phrases au format Unicode hindis (UTF-8).

+1

S'il vous plaît modifier cette question et utiliser la mise en forme appropriée de sorte que la question est lisible –

Répondre

6

En règle générale, ne pas processus chaînes d'octets codés: les faire en chaînes unicode appropriées (en appelant leur méthode .decode) le plus tôt possible, faire tout votre traitement toujours sur les chaînes unicode, alors, si vous avez pour les E/S, .encode leur retour dans tout encodage bytestring dont vous avez besoin.

Si vous parlez littéraux, comme il semble que vous êtes dans votre code, le « le plus tôt possible » est à la fois: utiliser u'...' pour exprimer vos littéraux. Dans un cas plus général, où vous êtes obligé de faire des E/S sous forme codée, c'est immédiatement après l'entrée (tout comme c'est juste avant la sortie si vous avez besoin d'effectuer une sortie sous une forme codée spécifique).

+0

Bonjour Monsieur .. :) Merci pour votre réponse .. tout ce que vous avez dit dans le 2ème para est exactement applicable à mon cas .. J'ai essayé cette chose dans la ligne suivante du code: trans = u'Word (imprimables) ' et je ne pouvais pas atteindre la sortie désirée. Pourriez-vous s'il vous plaît me corriger si j'ai fait la modification dans la mauvaise ligne, car après avoir fait ce changement, l'erreur arrive 'Attendant les imprimables à cette position' par rapport aux lignes qui définissent la grammmar. – boddhisattva

+0

@mgj, n'attribuez pas de chaîne littérale unicode à 'trans', cela n'a aucun sens. Assurez-vous simplement que 'printables' est un objet unicode (** pas ** une chaîne d'octets codée par utf8! - ni une chaîne d'octets avec un autre encodage!), Et utilisez' trans = Word (printables) '. Si votre fichier est encodé en utf-8, ou encodé avec un autre encodage, décodez-le en utilisant codecs.open depuis le module 'codecs', _not_ le' built' intégré comme vous le faites, de sorte que chaque ' line' est un objet unicode, pas une chaîne d'octets (quel que soit le codage). –

21

printables de pyparsing traite uniquement des chaînes dans la plage ASCII de caractères.Vous voulez printables dans la gamme Unicode complète, comme ceci:

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

Vous pouvez maintenant définir trans en utilisant cet ensemble de caractères non-espace plus complet:

trans = Word(unicodePrintables) 

Je ne pouvais pas tester contre votre Hindi chaîne de test, mais je pense que cela va faire l'affaire.

(Si vous utilisez Python 3, alors il n'y a pas de fonction unichr séparée, et aucun générateur de xrange, il suffit d'utiliser:

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

Merci pour votre réponse monsieur .. :) – boddhisattva

+0

cette réponse est depuis longtemps obsolète: unicode n'est plus 16 bits, et en boucle tout n'est pas performant du tout. –

+2

@flyingsheep - bonne astuce, mise à jour pour utiliser 'sys.maxunicode' au lieu d'une constante codée en dur, donc elle suivra avec le module' sys' de Python. Comme pour tout faire en boucle, ce bit ne s'exécute qu'une fois, lors de la définition initiale d'un analyseur, et lorsqu'il est utilisé pour créer un pyparse 'Word', il est stocké en set(), donc les performances d'analyse en temps sont encore bonnes. – PaulMcG

Questions connexes