Artículo original: Regular Expressions for Visual FoxPro Part 3
http://www.sweetpotatosoftware.com/SPSBlog/PermaLink,guid,9a28ad22-b41b-434a-a540-40e6197a099e.aspx
Autor: Craig Boyd
Traducido por: Ana María Bisbé York
FLL actualizada con más funcionalidad
No tengo tiempo (es tarde) para comentar mucho sobre los cambios que he hecho en regexp.fll. He mejorado significativamente las funcionalidades de la función regexp() cuando corta la cadena. Ahora se pueden guardar los pedazos cortados en una matriz o en un cursor. He mejorado además un par de errores en el código que tenían que ver con la fragmentación de la cadena. La documentación de mi entrada de blog anterior es válida para cada evento, vea (https://www.sweetpotatosoftware.com/blog/index.php/2006/01/11/regular-expressions-in-visual-foxpro-part-2/). (Nota del Editor: Traducido en este blog en Expresiones regulares en Visual FoxPro - Parte 2). Ahora se puede asignar 4 al parámetro nFunctionType y se obtendrá un cursor. Además, si está utilizando los valores 3 ó 4 para nFunctionType, puede especificar un comando de Visual FoxPro al motor de expresiones regulares para que lo ejecute cada vez que encuentre una coincidencia (pensado como una especie de función de rellamada -callback function )
Un ejemplo de análisis XML
Esta biblioteca ha tomado forma; pero pienso que existen muchas otras posibilidades que no se han explorado aun (Coméntenme en el blog o envíenme cualquier idea de funcionalidad que pueda tener -me encanta recibirlas). Algo nuevo que he pensado para la biblioteca puede ser análisis de XML. Utilicé alguna expresión regular que encontré disponible libremente en internet, creé un código de ejemplo (vea debajo) para mostrar las maravillosas habilidades de las expresiones regulares así como la nueva funcionalidad en la FLL.
Más por venir
Aun no he hecho justicia a las expresiones regulares ni a esta FLL. Cuando tenga más tiempo, regresaré a actualizar la documentación y mostrar cómo esta FLL ofrece posibilidades en Visual FoxPro que aun no hemos visto. He aquí un archivo de descarga y algunos ejemplos de código (la función ParseXML es lo fundamental que necesita la regexp.fll más reciente para poderla ejecutar). ¡¡ A disfrutar !!
Descarga de regexp.fll (63 KB aprox) haciendo clic aquí
*!* Ejemplo de empleo de la función ParseXML #DEFINE CREATEANARRAY 2 #DEFINE CREATEACURSOR 3 LOCAL lcArrayToCreate, lcCursorToCreate, lnTotal, lnCounter *!* He aquí un ejemplo de XML *!* sólo como demostración TEXT TO lcSampleXML NOSHOW PRETEXT 7 <?xml version="1.0"?> <samples> <sample>Visual FoxPro Rocks!</sample> <sample>Hace mucho más antes de desayunar</sample> <sample>que otros lenguajes hacen durante todo el día</sample> </samples> ENDTEXT *!* O puede intentarlo utilizando un archivo XML *!* Puede obtener algún ejemplo de XML desde *!* ftp://sunsite.unc.edu/pub/sun-info/standards/xml/eg/shakespeare.1.01.xml.zip *!* Una vez extraído comente del código encima TEXT/ENDTEXT *!* finalmente puede hacer algo como lo siguiente *!* para cargar el ejemplo de archivos XML *!* lcSampleXML = FILETOSTR(GETFILE()) *!* Crea una matriz DIMENSION aryXMLDoc(1) lcArrayToCreate = "aryXMLDoc" lnTotal = ParseXML(lcSampleXML, lcArrayToCreate, CREATEANARRAY) CLEAR FOR lnCounter = 1 TO lnTotal ? aryXMLDoc(lnCounter) ENDFOR MESSAGEBOX("El XML analizado se mostrará en pantalla desde la matriz." ; + CHR(13) + "Oprima OK para continuar con el siguiente ejemplo.", ; 64, "Análisis del XML terminado") *!* Crea un cursor lcCursorToCreate = "crsXMLDoc" lnTotal = ParseXML(lcSampleXML, lcCursorToCreate, CREATEACURSOR) IF lnTotal > 0 GO TOP IN (lcCursorToCreate) BROWSE ENDIF MESSAGEBOX("Oprima OK para ejecutar el ejemplo final.", ; 64, "Inicio del ejemplo final de Análisis del XML") *!* Crea un cursor; pero además ejecuta código *!* VFP que ejecuta el analizador C++. *!* Puede ser utilizado para manipular el dato *!* como es recuperado, o lo que sea. *!* El analizador C++ en la FLL *!* ejecutará cualquier comando que se le indique lcCursorToCreate = "crsXMLDoc" lcVFPCommand = "DO AppendVFPRocks" lnTotal = ParseXML(lcSampleXML, lcCursorToCreate, CREATEACURSOR, lcVFPCommand) IF lnTotal > 0 CLEAR GO TOP IN (lcCursorToCreate) SCAN ALL ? Splits ENDSCAN ENDIF ************************** PROCEDURE AppendVFPRocks ************************** Replace splits WITH "VISUAL FOXPRO ROCKS!" + splits ENDPROC ******************************* FUNCTION ParseXML (tcXML, tcName, tnType, tcCommand) ******************************* *!* Esta función existe gracias *!* al trabajo de Robert Cameron... ******************************* *!* REX/Perl 1.0 *!* Robert D. Cameron "REX: XML Shallow Parsing with Regular Expressions", *!* Technical Report TR 1998-17, School of Computing Science, Simon Fraser *!* University, November, 1998. *!* Copyright (c) 1998, Robert D. Cameron. *!* El código siguiente puede ser utilizado libremente y distribuido indicando este *!* copyright y citar en una nota que se mantiene intacta y si tiene modificaciones *!* o agregados han de ser debidamente identificados. *!* http://www.cs.sfu.ca/~cameron/REX.html ******************************* *!* 01-14-2006: Traducidas y modificadas sus expresiones *!* para uso en Visual FoxPro con regexp.fll *!* por Craig Boyd http://www.sweetpotatosoftware.com/spsblog ******************************* LOCAL lcTextSE, lcUntilHyphen, ; lcUntil2Hyphens, lcCommentCE, lcUntilRSBs, ; lcCDATA_CE, lcS, lcNameStrt, lcNameChar, ; lcName, lcQuoteSE, lcDT_IdentSE, ; lcMarkupDeclCE, lcS1, lcUntilQMs, ; lcPI_Tail, lcDT_ItemSE, lcDocTypeCE, ; lcDeclCE, lcPI_CE, lcEndTagCE, lcAttValSE, ; lcElemTagCE, lcMarkupSPE, lcXML_SPE, ; lcExpression, lvReturn IF !("\REGEXP.FLL" $ SET("Library")) SET LIBRARY TO LOCFILE("regexp.fll", "FLL") ENDIF lcTextSE = "([^<]+" lcUntilHyphen = "[^-]*-" lcUntil2Hyphens = lcUntilHyphen + "(?:[^-]" + lcUntilHyphen + ")*-" lcCommentCE = lcUntil2Hyphens + ">?" lcUntilRSBs = "[^\]]*](?:[^\]]+])*]+" lcCDATA_CE = lcUntilRSBs + "(?:[^\]>]" + lcUntilRSBs + ")*>" lcS = "[ \n\t\r]+" lcNameStrt = "[A-Za-z_:]|[^\x00-\x7F]" lcNameChar = "[A-Za-z0-9_:.-]|[^\x00-\x7F]" lcName = "(?:" + lcNameStrt + ")(?:" + lcNameChar + ")*" lcQuoteSE = '"[^"]*"|' + "'[^']*'" lcDT_IdentSE = lcS + lcName + "(?:" + lcS + "(?:" + lcName + "|" + lcQuoteSE + "))*" lcMarkupDeclCE = '(?:[^\]"' + "'><]+|" + lcQuoteSE + ")*>" lcS1 = "[\n\r\t ]" lcUntilQMs = "[^?]*\?+" lcPI_Tail = "\?>|" + lcS1 + lcUntilQMs + "(?:[^>?]" + lcUntilQMs + ")*>" lcDT_ItemSE = "<(?:!(?:--" + lcUntil2Hyphens + ">|[^-]" + lcMarkupDeclCE + ")|\?" ; + lcName + "(?:" + lcPI_Tail + "))|%" + lcName + ";|" + lcS lcDocTypeCE = lcDT_IdentSE + ; "(?:" + lcS + ")?(?:\[(?:" + lcDT_ItemSE + ")*](?:" + lcS + ")?)?>?" lcDeclCE = "--(?:" + lcCommentCE + ; ")?|\[CDATA\[(?:" + lcCDATA_CE + ")?|DOCTYPE(?:" + lcDocTypeCE + ")?" lcPI_CE = lcName + "(?:" + lcPI_Tail + ")?" lcEndTagCE = lcName + "(?:" + lcS + ")?>?" lcAttValSE = '"[^<"]*"|' + "'[^<']*'" lcElemTagCE = lcName + "(?:" + lcS + lcName + ; "(?:" + lcS + ")?=(?:" + lcS + ")?(?:" + lcAttValSE + "))*(?:" + lcS + ")?/?>?" lcMarkupSPE = "<(?:!(?:" + lcDeclCE + ")?|\?(?:" + lcPI_CE + ; ")?|/(?:" + lcEndTagCE + ")?|(?:" + lcElemTagCE + ")?))" lcXML_SPE = lcTextSE + "|" + lcMarkupSPE lcExpression = lcXML_SPE IF VARTYPE(tcCommand) = "C" lvReturn = RegExp(tcXML, lcExpression, tnType, tcName, tcCommand) ELSE lvReturn = RegExp(tcXML, lcExpression, tnType, tcName) ENDIF RETURN (lvReturn) ENDFUNC