Jugando con Expresiones Regulares en diferentes escenarios (XSD, .NET Framework, Python...)
En un algun momento seguro que todo el mundo necesitamos ayuda de las potentes expresiones regulares, cuyas reglas y sintaxis es igual en cualquier plataforma, pudiendo diferir el modo interno de procesamiento en rapidez o eficiencia.
Un escenario muy habitual de uso son los esquemas de XML (xsd), donde podemos encontrar la etiqueta pattern, la cual nos permite especificarle el patrón que una determinado elemento de nuestro XML debe cumplir. Lo que debemos de tener claro es que dicha etiqueta pattern indica una plantilla rígida que todo contenido del elemento afectado deberá cumplir. Veamos un ejemplo para especificar un cojunto de palabras alfa-numéricas separadas por comas.
Esquema que debe cumplir nuestro XML de ejemplo
<xs:element name="PalabrasClaves" type="TipoPalabrasClaves"/>
<xs:simpleType name="TipoPalabrasClaves">
<xs:restriction base="xs:string">
<xs:pattern value="(([a-zA-Z0-9])+)((,([a-zA-Z0-9])+)*)"/>
</xs:restriction>
</xs:simpleType>
Veamos ahora fragmentos de documentos XML que cumplen dicho patrón:
<PalabrasClaves>Casa,pepe,mochila,casa2 </PalabrasClaves>
<PalabrasClaves>perro</PalabrasClaves>
Veamos ahora fragmentos de documento XML que NO cumplen el patrón, es decir, darían lugar a un documento XML no válido:
<PalabrasClaves>Ca#sa, &Pepe</PalabrasClaves>
<PalabrasClaves>casa,</PalabrasClaves>
<PalabrasClaves>#pepe</PalabrasClaves>
--------------------------------------------------------------------------------------
Ahora nos vamos a otros escenarios, por ejemplo la librería System.Text.RegularExpressions del Framework .NET o la librería re de Python. Digamos que quisierámos saber si una expresión es válida o no usando dichas herramientas.
En C#, un posible código de ejemplo que podrías pensar en un principio de novatos sería algo tal que:
if ( Regex.isMatch( string_expresion_a_validar , (([a-zA-Z0-9])+)((,([a-zA-Z0-9])+)*) ) )
Console.WriteLine("VÁLIDO!");
else
Console.WriteLine("NO VÁLIDO");
Algo semejante podríamos hacer en Python:
import re
patron=re.compile("(([a-zA-Z0-9])+)((,([a-zA-Z0-9])+)*)")
result= patron.match('string_expresion_a_validar')
if result != None:
print result.string[result.start():result.end()]
En estos casos no esperemos un resultado equivalente a lo sucedido anteriormente, ya que las funciones match comprueban si hay alguna coincidencia en nuestra cadena, no estableciendo la rigidez que antes exigían la propiedad pattern de los esquemas XML. Concretamente, los ejemplos que antes nos erán válidos, ahora obtendríamos que la función IsMatch nos devuelve true y la función match de Python nos devolvería el primer framento coincidente si lo hay, pudiéndose así causar confusiones y creer que nuestras cadenas son totalmente válidas.
Un programita muy completo para el tratamiento de expresiones regulares es Expresso, el cual muestra, entre otras muchas opciones, un despiece completo de una cadena analizada, indicando de forma gráfica las partes coincidentes, las que no...; recomiendo que lo descargueis si vais a probar cosas de este tipo.