Artículo original: FoxPro Rocks Parsing Data
http://rickschummer.com/blog/2006/04/foxpro-rocks-parsing-data.html
Autor: Rick Schummer
Traducido por: Ana María Bisbé York
La semana pasada uno de mis clientes me envió un correo pidiéndome ayuda para analizar unos datos. Tenía un montón de documentos que se emplean en su industria, todos guardados en campos memos. Comenzaron a preparar una tabla de contenidos (que tenía el número de página y la guía de puntos). Cada una de las sesiones dentro del campo memo tenía un encabezado que estaba incluido en la tabla de contenidos.
Mi misión era obtener un código para analizar el campo memo y dividirlo en registros individuales para cada sección que había en el campo memo. Si el campo memo tenía 53 entradas en la tabla de contenidos, yo debía tener 53 registros en la tabla resultante. El contenido para cada sección era variable. Podía no haber texto alguno, podían haber varios párrafos de texto, o un término medio entre estos. Si la tabla de contenidos tenía, al menos, una entrada tendría el encabezado en el texto. El código necesitaba colocar el encabezado en una columna y toda la sesión correspondiente en un campo memo.
¿Quiere adivinar cuánto tiempo me llevó escribir y cuántas líneas de código? Adelante, hágase una idea aproximada. Mi idea fue que tardaría 60 minutos. No tenía idea de la cantidad de líneas que necesitaría.
Escribí la parte inicial de la solución en menos de una hora. Analicé la tabla de contenidos utilizando ALINES() y luego analicé los encabezados de sesiones a partir de la tabla de contenidos, buscando todos los textos que aparecían antes de la guía de puntos. Extraje todo el texto entre los encabezados de sección en el resto del memo utilizando STREXTRACT(). Desafortunadamente algunas de las palabras en el memo se duplicaron en la tabla de contenido. Me tomó unos minutos revisar los datos duplicados, limpiar algunos espacios extras y retornos.
La solución que preparé para el usuario es el siguiente código que también lo pueden descargar desde: ParseMemoViaTableOfContents.zip
LOCAL lcDots, ;
lcNextChapter
LOCAL ARRAY laMemo[1]
CREATE TABLE ParsedMemo ;
( ;
cChapter c(200), ;
mChapter m ;
)
SCATTER MEMO BLANK NAME loData
lcDots = "..............."
lnLines = ALINES(laMemo, MemoTestFree.FannieMemo)
SET STEP ON
FOR lnI = 2 TO lnLines
IF lcDots $ laMemo[lnI]
loData.cChapter = SUBSTRC(laMemo[lnI], 1, ATC(lcDots, laMemo[lnI]) - 1)
lcNextChapter = SUBSTRC(laMemo[lnI+1], 1, ATC(lcDots, laMemo[lnI+1]) - 1)
* Find occurance with exact match, stating
* with second occurence (one after table of contents
lnY = 2
DO WHILE .T.
loData.mChapter = STREXTRACT(MemoTestFree.FannieMemo, loData.cChapter, lcNextChapter, lnY, 2+4)
DO CASE
CASE EMPTY(loData.mChapter)
* Nothing returned, bail
EXIT
CASE NOT (lcDots $ loData.mChapter)
* Strip out delimiters since this is not another TOC entry
loData.mChapter = STREXTRACT(MemoTestFree.FannieMemo, loData.cChapter, lcNextChapter, lnY, 2)
EXIT
OTHERWISE
* Keep going, found a near match but not exact match
lnY = lnY + 1
ENDCASE
ENDDO
* Remove all the initial extra spaces, carriage returns, linefeeds, and tabs
DO WHILE INLIST(SUBSTRC(loData.mChapter, 1, 1), SPACE(1), CHR(13), CHR(10), CHR(9))
loData.mChapter = SUBSTRC(loData.mChapter, 2)
ENDDO
INSERT INTO ParsedMemo FROM NAME loData
ELSE
EXIT
ENDIF
ENDFOR
RETURNTodo está programado en 61 líneas de código (incluyendo algunas pocas líneas de comentarios y algunas líneas en blanco). La capacidad de VFP para analizar gramáticamente texto es excelente ¿A que si?
Se que el cliente quedó muy satisfecho.
ME SACO EL SOMBRERO
ResponderBorrar