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 RETURN
Todo 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