Versión para imprimir / Salvar en Favoritos
Expresiones regulares con VBScript
Las expresiones regulares, y su uso mediante el objeto RegExp, son una de las características más potentes pero desconocidas de VBScript y JScript. Nos permiten comprobar si una cadena de texto sigue un patrón predeterminado, o buscar complejas subcadenas y reemplazarlas automáticamente, lo cual es muy útil a la hora de manejar textos, cadenas y datos introducidos por los usuarios.
Introducción
Definir las expresiones regulares es difícil, puesto que tendríamos que hablar de vocabularios, lenguajes... Como anécdota os contaré que oí hablar de ellas por primera vez en una asignatura, Informática Teórica, que en principio me sonaba bastante alejada de la programación.
Las expresiones regulares son una representación de un lenguaje. Sí, suena muy teórico, pero es así. Una ER establece un patrón que verifica que una palabra pertenece a un lenguaje. No hablo de lenguajes de programación ni de idiomas: hablo de un conjunto de símbolos. Eso es un lenguaje.
Supongamos que tenemos un lenguaje que sólo admite ceros (0) y unos (1). En ese lenguaje con sólo dos "letras", una palabra sería: 0101 y otra 00101. Podemos expresar las posibles combinaciones con una ER.
Bien, volvamos a la Tierra. :-)
Expresiones regulares en VBScript
VBScript ofrece el objeto RegExp para trabajar con expresiones regulares. Desde el punto de vista práctico, nos permite definir un patrón y comprobar si ese patrón tiene alguna coincidencia en una cadena. La sintaxis para definir el patrón es bastante extraña en un principio si no has oído nada de expresiones regulares antes.
En general, el patrón especifica qué símbolos (dígitos, letras) pueden aparecer dónde y cuántas veces. Por ejemplo, el siguiente patrón indica que la cadena debe empezar con un dígito:
^\d
El sombrerito (^) indica que lo que viene a continuación se refiere al principio de la cadena. \d indica que se trata de un dígito.
Casi todas las secuencias y caracteres especiales se escriben con la barra delante (\). Para escapar un carácter especial, utilizamos también la barra, al igual que para escapar unas comillas en VBScript ponemos otras comillas delante.
Vamos a ver alguno de los caracteres especiales más útiles:
\: Marca el siguiente carácter como especial o literal. Por ejemplo, como el punto (.) es un caracter especial, \. indica un punto normal. En cambio, \d indica un dígito.
^: hace coincidir con el comienzo de la cadena.
$: hace coincidir con el final de la cadena. El ejemplo anterior cambiado a: \d$ indica que la cadena debe terminar con un dígito.
*: indica que lo anterior puede existir 0 o más veces.
+: indica que lo anterior puede existir 1 o más veces.
x|y: indica que o bien coincide x o bien coincide y. Un or, vamos...
[a-z]: indica un rango de caracteres. Por ejemplo, "[0-9]" aceptaría cualquier dígito entre 0 y 9.
[abc]: un conjunto de caracteres. Coincide con uno de ellos. Por ejemplo, "[Aa]bc" coincide con Abc y también con abc.
{n}: indica que lo anterior debe aparecer exactamente n veces. Por ejemplo, "/d{3}" indica que deben aparecer exactamente 3 dígitos.
\d: coincide con un dígito, como [0-9].
\w: coincide con un carácter de palabra incluyendo el subrayado.
\b: coincide con el final de una palabra. Por ejemplo, "a\b" coincide con "casa", pero no con "cardo".
\B: coincide con un no final de palabra en oposición a la anterior.
Para que os hagáis una idea, las ER no sólo sirven para VBScript: el comando grep de Unix, por ejemplo, acepta expresiones regulares. Esta línea:
grep [Hh]ola *.txt
Nos devolvería el fichero y numero de línea donde encuentre "Hola" u "hola" entre todos los ficheros .txt del directorio. (gracias flynn por recordármelo!) :-)
Utilizar el objeto RegExp
Supongo que estaréis bastante extrañados de todo esto. Haced un pequeño esfuerzo y os veréis recompensados, palabra... Vamos a explicar primero cómo funciona el objeto RegExp y nos ponemos a hacer ejemplos.
Para instanciar el objeto, utilizamos:
<%
Dim oER
'¡Nada de Server.CreateObject!
set oER = New RegExp
Para definir un patrón, se utiliza la propiedad Pattern:
oER.Pattern = "^\d"
Y para probarlo contra una cadena, podemos utilizar el método Test que devuelve Verdadero o Falso si encontró una coincidencia con el patrón.
Response.Write oER.Test("345")
Nos imprimiría True, porque la cadena comienza con un dígito.
Tenemos otra propiedad útil, que especifica si debe ignorar o no las mayúsculas y minúsculas:
oER.IgnoreCase = True hará que ignora la diferencia entre mayúsculas y minúsculas.
Ejemplos al fin...
Para aprender a emplear expresiones regulares lo mejor es comenzar con patrones sencillos e ir complicándolos poco a poco, para ver las diferencias.
Vamos a hacer una página ASP sencilla, para ir modificando y probando:
<%
Dim oER, patron, cadena
patron = ""
cadena = ""
set oER = New RegExp
oER.Pattern = patron
oER.IgnoreCase = True
if oER.Test(cadena) then
Response.Write("<p>La cadena coincide con el patrón.")
else
Response.Write("<p>La cadena no coincide con el patrón.")
end if
set oER = nothing
%>
Salvad la página como test_er.asp y ponedla en un directorio compartido con la Web.
Así, si tenemos abierto el código y el navegador, simplemente modificando las dos primeras líneas, salvando y actualizando podemos probar nuestras expresiones regulares.
Vamos a empezar con cosas fáciles: queremos ver que la cadena no contiene dígitos, solo letras, guión bajo o guión normal. Ponemos entonces patron como:
patron = "[a-zA-Z-_]"
cadena = "25dediciembre"
Esto es lo que significa el patrón:
[a-zA-Z-_] |
Coincide cualquier carácter entre a-z, A-Z, y también el guión (-) y el subrayado (_) |
En teoría no debería concidir: nuestra cadena 25dediciembre contiene números. Cargamos la página y nos dice que si coincide. ¿Qué pasa aquí?
Pues que el objeto RegExp busca coincidencias con el patrón que le damos pero también como subcadenas. Nos ha devuelto verdadero porque efectivamente, dediciembre coincide con el patrón. Tenemos que especificar que ésa sea toda la cadena, con los símbolos ^ al principio y $ al final.
patron = "^[a-zA-Z-_]$"
Salvamos y ahora sí, la cadena no coincide.
Pero esto no significa que esté bien... Poned como cadena = "asp" y probad. ¡No coincide! Nosotros queremos una cadena de sólo caracteres y "asp" lo es... Pero no hemos dicho que se pueden repetir, así que "a" sí es válido pero "asp" no.
Reescribimos la ER así:
patron = "^[a-zA-Z-_]+$"
cadena = "asp"
Esto es lo que significa el patrón:
^ |
Coincide con el principio de la entrada/línea |
[a-zA-Z-_] |
Coincide cualquier carácter entre a-z, A-Z, y también el guión (-) y el subrayado (_) |
+ |
Indica que lo anterior puede aparecer 1 o más veces |
$ |
Coincide con el final de la entrada/línea |
Ahora sí es válido. Si queremos que acepte también una cadena vacía, tendremos que poner el asterisco en lugar del signo más, para que acepte 0 apariciones.
¿Vais viendo el proceso? Fijaos que toda la expresión regular simplemente dice: "que empiece por un carácter alfabético o guión o subrayado, y que se repita tantas veces como quiera hasta el final". Os podéis ir haciendo una idea de la potencia de esto ¿verdad?
Vamos a hacer un ejemplo un poco más util: supongamos que pedimos en un formulario un número de teléfono, y queremos exigir que el formato sea: prefijo_zonal-nnnnnnn, algo como 91-4442211.
Queremos, por tanto, dos dígitos, un guión y siete dígitos más:
patron = "^[0-9]{2}-[0-9]{7}$"
cadena = "91-5552273"
Esto es lo que significa el patrón:
^ |
Coincide con el principio de la entrada/línea |
[0-9] |
Coincide cualquier dígito de 0 a 9 |
{2} |
Lo anterior coincide exactamente 2 veces |
- |
Nada raro: un guión |
[0-9] |
Coincide cualquier dígito de 0 a 9 |
{7} |
Lo anterior coincide exactamente 7 veces |
$ |
Coincide con el final de la cadena |
La siguiente expresión comprueba que la entrada está formada por de 1 a 8 caracteres de texto, un punto y una cadena de tres caracteres: o bien gif, o bien jpg o bien png.
patron = "^\w{1,8}\.(gif|jpg|png)$"
Prueba cadenas, intenta "engañar" al programa: sólo aceptara nombres de fichero JPEG, GIF o PNG válidos (limitados a 8.3 caracteres, por supuesto).
Aquí tienes la explicación del patrón:
^ |
Coincide con el principio de la entrada/línea |
\w |
Corresponde con cualquier carácter alfabético y el guión bajo. |
{1,8} |
Coincide por lo menos con una aparición y como máximo ocho del carácter anterior. |
\. |
Como el punto es un carácter especial (coincide con cualquier carácter excepto el de nueva línea) tenemos que escaparlo con la barra, para tomarlo como un punto corriente. |
(gif|jpg|png) |
Coincide con una de las cadenas "gif", "jpg" o "png". |
$ |
Coincide con el final de la cadena |
Para terminar, vamos a hacer un patrón que nos valide un nombre de usuario. Supongamos que tenemos un sitio Web donde la gente se registra, y no queremos permitir vocales acentuadas en el nombre ni algunos caracteres raros (!, ", #, $, %, &, !, ¡)
Simplemente definimos la expresión regular para que busque estos caracteres, y si nos da verdadero en este caso, no nos serviría el nombre:
patron = "[á|é|í|ó|ú|!|""|#|\$|%|&|!|¡]+"
Este patrón, si devuelve verdadero, indica que el nombre de usuario no es válido.
Es muy sencillo:
[x|y|z|..] |
Coincide con uno o varios de los caracteres dentro de los corchetes |
+ |
Coincide con al menos uno o varios del carácter anterior. |
\$ |
Al igual que ocurría antes, tenemos que escapar el símbolo del dólar, puesto que tiene un significado especial, con la barra. |
¿Te imaginas hacer todo esto con funciones como InStr y Mid? Las expresiones regulares ofrecen una potencia única para recorrer textos y cadenas, y validar datos introducidos por el usuario.
De momento eso es todo... Os dejo que practiquéis vuestra habilidad para acertar con los patrones. En el próximo artículo sobre el tema os presentaré algunas funciones interesantes para tratar con fechas, y como buscar coincidencias y reemplazarlas utilizando la colección Matches y el método Execute del objeto RegExp.
|
>> ¿Quieres saber cuándo se publicarán nuevos artículos? ¡Suscríbete al Boletín de ASPFácil! <<
|
|
>> Comparte tus dudas y comentarios sobre este artículo en el foro Artículos de ASPFácil <<
|
(Arriba)
|