2010-02-26 24 views
10

:) Intenté usar w = Word (imprimibles), pero no está funcionando. ¿Cómo debería dar las especificaciones para esto? 'w' está destinado a procesar caracteres Hindi (UTF-8)Python - Pyrersing caracteres Unicode

El código especifica la gramática y analiza en consecuencia.

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

Si hay sólo caracteres ingleses que está trabajando por lo que el código es correcto para el formato ASCII pero el código no funciona para el formato Unicode.

quiero decir que el código funciona cuando tenemos algo de la forma 671.assess :: :: ahsaas 2

es decir, se analiza sintácticamente las palabras en el formato de Inglés, pero no estoy seguro de cómo analizar y luego imprime caracteres en el formato Unicode. Necesito esto para la alineación de palabras en hindi en inglés para el propósito.

El código Python tiene el siguiente aspecto:

# -*- 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 un ejemplo frase de entrada para el archivo de origen es:

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

la ouptut se vería así: -

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

Explicación de salida: - Esto logra una alineación bidireccional. Significa la primera palabra de los mapas 'modernos' en inglés para la primera palabra de hindi 'AddhUnIk' y viceversa. Aquí incluso los caracteres se toman como palabras, ya que también son una parte integral del mapeo bidireccional. Por lo tanto, si observas la palabra hindi '.' tiene una alineación nula y se mapea a nada con respecto a la oración en inglés ya que no tiene un punto final. La tercera línea en la salida básicamente representa un delimitador cuando estamos trabajando para un número de oraciones para las cuales trata de lograr un mapeo bidireccional.

Qué modificación debo hacer para que funcione si tengo las frases hindi en formato Unicode (UTF-8).

+1

favor editar esta cuestión y hacer uso de formato adecuado para que la cuestión es legible –

Respuesta

6

Como regla general, hacen no cadenas de bytes de proceso codificado: hacen en cadenas Unicode apropiadas (llamando a su método .decode) tan pronto como sea posible, hacer todo de su procesamiento siempre en cadenas Unicode, entonces, si usted tiene para fines de E/S, .encode devuélvalos a la codificación de bytes que desee.

Si estás hablando de literales, ya que parece que está en su código, el "tan pronto como sea posible" es a la vez : utilizar u'...' para expresar sus literales. En un caso más general, donde se lo fuerza a hacer E/S en forma codificada, es inmediatamente después de la entrada (tal como está inmediatamente antes de la salida si necesita realizar una salida en un formulario codificado específico).

+0

Hola señor ... :) Gracias por su respuesta. Lo que usted dijo en el 2 ° párrafo es exactamente aplicable a mi caso. Intenté esto en la siguiente línea del código: trans = u'Word (imprimibles) ' y no pude lograr la salida deseada. ¿Podría corregirme si he hecho la modificación en la línea incorrecta, ya que después de hacer este cambio aparece el error 'Esperando imprimibles en esa posición' con respecto a las líneas que definen el grammmar. – boddhisattva

+0

@mgj, no asigne un literal de cadena unicode a 'trans', eso no tiene sentido. Solo asegúrese de que 'imprintables' sea un objeto unicode (** no ** una cadena de bytes codificada en utf8! - ni una cadena de bytes con cualquier otra codificación!), Y use' trans = Word (imprimibles) '. Si su _file_ está codificado en utf-8, o codificado con cualquier otra codificación, decodifíquelo usando 'codecs.open' del módulo' codecs', _not_ el 'open' integrado como lo está haciendo, de modo que cada' line' es un objeto Unicode, no una cadena de bytes (en cualquier codificación). –

21

Pyparsing's printables solo trata con cadenas en el rango de caracteres ASCII.¿Quieres imprimibles en la gama completa de Unicode, así:

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

Ahora puede definir trans el uso de este conjunto más completo de caracteres no espaciales:

trans = Word(unicodePrintables) 

he podido probar en contra de su Hindi cadena de prueba, pero creo que esto hará el truco.

(Si está utilizando Python 3, entonces no hay ninguna función unichr separada, y no de un generador xrange, sólo tiene que utilizar:

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

Gracias por su respuesta, señor ... :) – boddhisattva

+0

esta respuesta hace tiempo que está obsoleta: el unicode ya no tiene 16 bits, y el bucle de todo no funciona en absoluto. –

+2

@flyingsheep - buen consejo, actualizado para usar 'sys.maxunicode' en lugar de una constante codificada, por lo que seguirá con el módulo' sys' de Python. En cuanto a iterar todo, este bit solo se ejecuta una vez, cuando se define inicialmente un analizador, y cuando se usa para crear un pyparsing 'Word', se almacena como un conjunto(), por lo que el rendimiento del tiempo de análisis sigue siendo bastante bueno. – PaulMcG

Cuestiones relacionadas