jueves, 7 de agosto de 2025

Textos. OOo Basic

Limpieza y segmentación de textos


No es fácil definir el objetivo de estos procesos, como tampoco lo es ejecutarlos, ya que es necesario definir antes con qué objetivo. Y es que los objetivos pueden ser muchos y de diferente naturaleza. Dado que nos situamos dentro de una sección dirigida al tratamiento (automatización) de textos, me centraré en aquello que deriva en el conjunto de objetivos que pueden llevar a tal fin, eludiendo (por ahora y en este bloque de contenidos) otros objetivos más enfocados al análisis del contenido textual, por corresponder a otras secciones del Blog.


Retomando el hilo y limitando las pretensiones a la automatización de la composición textual, quedó clara en [esta entrada] la importancia de la segmentación del contenido, y ya vimos que ésta toca hacerla "a mano", por lo menos hasta que dispongamos de medios que nos permitan abordar el proceso de otra forma. Pero lo cierto es que este procedimiento nos acerca a otras posibilidades que parten de los mismos principios (y medios) que nos permitieron segmentar el texto-base en segmentos con significado y de relevancia para la automatización. 

Me refiero a las funciones que nos permiten descomponer (Split()) y recomponer (Join()) cadenas, que usadas de forma combinada y en combinación con matrices y bucles nos permiten modificar el contenido y la estructura del texto, algo que resulta ser de mucha utilidad en el tratamiento de textos extensos y complejos y que posiblemente facilite el desarrollo de estrategias de automatización de este tipo de textos.

Quiero mostrar en esta entrada cómo crear estos procedimientos, aunque no es posible hacerlo sin limitarnos al logro de algún objetivo quizá demasiado simple, por lo que sólo puede darnos una idea general de las posibilidades que encierra.

Como texto-base voy a emplear uno de [Germán Portillo] titulado "¿Por qué es rosado el lago Hillier?" (adaptado), y como objetivo me planteo eliminar los signos de puntuación y lograr la división del texto en un listado exclusivamente de palabras. Este es el código del script:

Sub CrearMatrizPalabras

'FASE 1 - Accedo a la hoja TextoBase
Dim oHoja As Object
oHoja = ThisComponent.getCurrentController.getActiveSheet()
'... a la celda A1 que contiene el texto
Dim oTexto As Object
oTexto = oHoja.getCellRangeByName( "A1" )
'... y al textoi que contiene la celda A1
Dim sTexto As String
sTexto = oTexto.getString()

'FASE 2 - Limpieza de signos de puntuación del texto
Dim mSignos() As String
Dim sTextoResultante As String
Dim mMatrizPalabras() As String
Dim i As Integer

mSignos() = Array(",",";",".","(",")","¿","?"," ","--")

sTextoResultante = sTexto

For i = 0 To UBound(mSignos())
mMatrizPalabras = Split(sTextoResultante,mSignos(i))
sTextoResultante = Join(mMatrizPalabras(),"-")
Next

'FASE 3 - Creo la matriz final y copio sus elementos en hoja MatrizBase
Dim mMatrizFinal() As String

mMatrizFinal = Split(sTextoResultante,"-")

'Creo la hoja MatrizBase
Dim oHojas As Object
oHojas = ThisComponent.getSheets()
oHojas.insertNewByName("MatrizBase", 2)

Dim oHojaMatrizBase As Object
oHojaMatrizBase = ThisComponent.getSheets().getByName("MatrizBase")

'Copio el contenido de la matriz mMatrizFinal() en la columna A
For i = LBound(mMatrizFinal()) To UBound (mMatrizFinal())
oTextoMatriz = oHojaMatrizBase.getCellRangeByName( "A" & i+1 )
oTextoMatriz.setString(mMatrizFinal(i))
Next

End Sub

Divido este script en tres fases; la primera, de sobra conocida, nos facilita el acceso al texto (1). La segunda fase contiene el núcleo fundamental del procedimiento, que se basa en el desarrollo de un bucle (For i = 0 To UBound(mSignos())) que recorre la matriz  que contiene los caracteres que nos interesa eliminar (mSignos() = Array(",",";",".","(",")","¿","?"," ","--")), ya que lo que realizamos es un proceso sucesivo de eliminación de caracteres, haciendo uso de las características de las funciones que se suceden en el bucle (2), siendo fundamental el orden en que se suceden:
  • En el primero (mMatrizPalabras = Split(sTextoResultante,mSignos(i))) se produce la segmentación del texto en base al elemento de la matriz (mSignos(i)), resultando de ello la eliminación del carácter.
  • En el segundo (sTextoResultante = Join(mMatrizPalabras(),"-")) se recompone la unidad del texto empleando como separador el carácter ("-"), a fin de identificar las diferentes partes cuando el texto se vuelva a dividir en segmentos gracias al siguiente paso del bucle.
La tercera y última fase parte del texto que resulta del proceso anterior y al que se aplica una última segmentación, precisamente en base al carácter empleado antes (mMatrizFinal = Split(sTextoResultante,"-")). El resto de esta fase consiste en facilitar que el resultado del proceso anterior no se pierda y quede disponible para posteriores tratamientos (oTextoMatriz.setString(mMatrizFinal(i))). Para ello se trasladan los segmentos resultantes a una hoja que se crea con este objetivo (oHojas.insertNewByName("MatrizBase", 2)) mediante un nuevo bucle (For i = LBound(mMatrizFinal()) To UBound (mMatrizFinal()))

Documento. Descarga [desde aquí] el documento-soporte.

Vuelvo a insistir que lo que obtenemos aquí es la base para el desarrollo de procesos posteriores, como puede ser la identificación de determinadas palabras (3), el recuento de la presencia de otras o su eliminación.


NOTAS

(1) Que en este ejemplo es proporcionado desde formato .txt, sin más modificación respecto al original que la eliminación de los saltos de línea. No se trata de un texto en el que previamente se hayan identificado (y marcado) determinados segmentos [como en el caso del texto-base] de nuestra última propuesta de automatización.
(2) Las funciones han sido tratadas [en esta entrada]
(3) Aquí sugiero un uso concreto, como puede ser la identificación del género gramatical asociado a la vi-nombre mediante la comprobación del género de las vg asociadas mediante la concordancia gramatical de género. Esto remite a lo expuesto [en esta entrada].

No hay comentarios:

Publicar un comentario

Comenta esta entrada