Desesperante historia con expresiones regulares y sustitición

Pablo Ruiz Múzquiz pablo en elenya.net
Lun Ene 17 00:55:37 CET 2005


Hola a todos,

He aquí un aparente sencillo problema de "search & replace" que se sale de 
madre en cuanto aparecen las tildes y otros caracteres "extraños".

La situación es la siguiente (el código va después):

- Tenemos un fichero java con un buen montón de setText("algo") en español.
- Tenemos un fichero llamado diccionario.txt en donde cada línea tiene la 
forma "textoenespañol;textoenportugués"
- Queremos el fichero en java con los setText("algo") en portugués.

La aproximación inicial de leer todas las líneas, realizar find sobre cada una 
de ellas y buscar ocurrencias del "textoenespañol" para sustituir por 
"textoenportugués" no es buena porque el find es muy ingenuo. Sustituirá 
cualquier texto, incluso sin estar dentro de un setText(). Además, si hacemos 
varias pasadas, items del diccionario como "ABC;ABCD" seguirán dando positivo 
y acabaremos con "ABCDDDD" al poco rato.

Así pues, nos vamos a las expresiones regulares. 

Ahora bien, el diccionario sólo lista los textos puros "Seleccionar;Escolher". 
Sin embargo, en el código java podríamos encontrarlos como:
setText("* Seleccionar:")
setText("Seleccionar :")
setText("seleccionar")
setText("seleccionar >>")

Así que generamos una expresión regular como la siguiente
'\"[ ]*\*?[ ]*' + k + '(\:?|\>*)\"'

donde la variable k es el texto en español de cada línea del diccionario. En 
todo momento trabajamos sin importarnos las mayúsculas o minúsculas.

El código (extracto) de traductor.java
--------------

for k,v in adict.items():
 p = re.compile('\"[ ]*\*?[ ]*' + funcion(k) + '(\:?|\>*)\"', re.L|re.I)
 match = p.search(string.lower(aline),re.L|re.I)
             
 if (match!=None): #la expr reg aparece.
  print "!",
  aline=re.sub(k,v,aline) #sustituimos
  print('Linea modificada: '+k+'por'+v) #indicamos el hecho

return aline
----------------

donde función "escapa" algunos caracteres sensibles en el contexto de 
expresiones regulares. (":", ";", "*", "\", " ", etc)


El contenido de fichero.java podría ser algo así:
-----------------
this.addTab("Datos Generales (CAB)", tabCABAir());
this.addTab("Datos Comerciales (AGMT)", tabAGMTAir());
this.addTab("facturación y Cobros (ACCT)", tabACCTAir());
jLabelCustomerName1.setText("Razón social:");
jLabelAddress2.setText("* Dirección:");
jLabelNumber1.setText("* Número:");
jLabelPostCode1.setText("* Código");
jLabelTown1.setText("* población:");
jButtonNextCAB.setText("Siguiente >>");
jLabelAddress4.setText("* Observaciones:");
jLabelAddress4.setText("* postal:");
------------------

Y, por último, el contenido de diccionario.txt
------------------
Datos Generales (CAB);Informação General (CAB)
Punto de Entrega (LOS);Ponto de Entrega (LOS)
Datos Comerciales (AGMT);Informação Comercial (AGMT)
Facturación y Cobros (ACCT);Facturação e Cobranças (ACCT)
Condiciones Comerciales (LOG);Logística  (LOG)
Siguiente;Seguinte
Razón Social;Customer Name
Número;No
Código;Code
Población;Town
Observaciones;comments
Postal:post
-------------------

Si ejecutamos el programa sobre fichero.java y diccionario.txt obtengo algo 
como:

! Linea modificada: Datos Generales (CAB) por Informação General General (CAB)
! Linea modificada: Datos Comerciales (AGMT) por Informação Comercial (AGMT)
! Linea modificada: Observaciones por comments
! Linea modificada: Postal por post

¡Sólo tres! Además, si miro el fichero.java resultante veo que, en realidad 
sólo ha modificado Observaciones ya que sucesivas pasadas me arrojan:

! Linea modificada: Datos Generales (CAB) por  Informação General (CAB)
! Linea modificada: Datos Comerciales (AGMT) por  Informação Comercial (AGMT)
! Linea modificada: Postal por post

De lo que se deduce:
a) Sólo entiende bien los textos sin tilde en español a pesar de indicarle que 
se fije en el locale.
b) Tiene en cuenta las mayúsculas y minúsculas cuando va a sustituir a pesar 
de que le indico que no se así (ej: Postal)

¿Alguna pista?

Muchísimas gracias,

Pablo Ruiz Múzquiz
------------ próxima parte ------------
_______________________________________________
Python-es mailing list
Python-es en aditel.org
http://listas.aditel.org/listinfo/python-es


Más información sobre la lista de distribución Python-es