Ir directamente al contenido de esta página

codexexempla.org

Expresiones regulares (1)

Tabla de contenidos

  1. Introducción
  2. ¿Expresiones regulares?
  3. Métodos de JavaScript que aceptan expresiones regulares
  4. Clases

Introducción

Cuando hace unas semanas me puse a escribir los scripts para los ejemplos de «Cuestiones de accesibilidad al validar un formulario», recordé que las expresiones regulares son uno de los mejores inventos después de la PSP. Así que aquí estoy, refrescando mi memoria, y porque, como dice mi profesor de aikido, «intentando enseñar es cuando de verdad se empieza a aprender».

Por supuesto, tanto este artículo como su continuación —«Expresiones regulares (2)»— no son más que una mera introducción. A medida que se avanza en el estudio de las expresiones regulares, la profundidad y la complejidad del tema dan para escribir libros de esos que dan miedo por su volumen. Por ejemplo, Mastering Regular Expressions de Jeffrey Friedl son 542 páginas, y Beginning Regular Expressions de Andrew Watt, 768.

¿Expresiones regulares?

Las expresiones regulares son patrones con los que describir de manera abstracta una cadena literal. Su función es servir como modelo con el que contrastar una cadena.

Supongamos, por ejemplo, que quiero saber si lo que ha introducido un usuario en un campo de formulario es un correo electrónico. Tendría que preguntar algo como «¿el texto que ha introducido el usuario no tiene espacios en blanco, al menos cuenta con un caracter antes de una arroba, tras ésta hay algún caracter antes de un punto y tras éste hay dos o tres caracteres alfabéticos?». Pues el modelo que corresponde a esta descripción es la expresión regular.

Hay dos formas de crear expresiones regulares:

Los parámetros son dos, y en la construcción de una expresión pueden aparecer ambos, uno o ninguno:

Las diferencias quedarán más claras en cuanto comencemos a trabajar sobre unos ejemplos.

Métodos del objeto String que aceptan expresiones regulares

Antes de empezar a explicar su sintaxis1, primero necesitamos saber qué métodos del objeto String aceptan expresiones regulares. Estos métodos son:

Vamos a ver un ejemplo. Si tenemos el siguiente literal, consistente en un famoso verso de Gertrude Stein


    var cadena = 'A Rose is a Rose is a Rose';        
            

y una expresión regular tan sencilla como


    var expr = /ro/i;        
            

nos devolvería:

Si ahora modificamos la expresión de esta manera:


    var expr = /ro/g;        
            

los resultados serían

Por último, si volvemos a modificar expr:


    var expr = /ro/gi;        
            

el resultado sería como para /ro/i salvo para match(), que devolvería una matriz compuesta por Ro, Ro y Ro, dado que ahora la expresión es global —y como hemos dicho, la comparación no se detiene en la primera coincidencia— e insensible.

Se pueden comprobar estos resultados en este ejemplo.

Por su parte, por medio de replace() se pueden sustituir las coincidencias de una expresión en una cadena por otra cadena.

Supongamos que ahora nuestra cadena es la extensión del acrónimo VALIS:


    var cadena = 'Vast Active Living Intelligence System';    
            

y aplicamos replace() así:

Éste es el ejemplo interactivo.

Hasta ahora he empleado en los ejemplos las expresiones regulares más sencillas, pero para luego crear expresiones más complejas hay una serie de caracteres que tienen su propio significado, y que por tanto deben escaparse. Los recojo a continuación:


    ( [ { \ ^ $ | ) ? * + .
                

Su sintaxis sería expr = /\(/; o expr = new RegExp('\\(');. Sí, en el objeto se hace un doble escape.

También se pueden identificar caracteres ASCII o Unicode empleando su código. Los primeros se expresan por medio de \x más el valor de dos dígitos hexadecimal correspondiente2; \x53, por ejemplo, es la «S». Los segundos se indican con \u y el valor hexadecimal de cuatro dígitos del caracter3; por ejemplo —y por si alguna vez se lo ha preguntado—, el código hexadecimal de la runa Tyr es \u16CF.

Y ya, por último, existen una serie de caracteres predefinidos:

  • \0: Vacío (null).
  • \a: El caracter de advertencia.
  • \b: El caracter de retroceso.
  • \c+código_de_control4: El código de control correspondiente.
  • \e: El caracter de escape.
  • \f: El caracter de avance de formulario.
  • \n: Un salto de línea.
  • \r: Un salto de carro.
  • \t: Un tabulado horizontal.
  • \v: Un tabulado vertical.

No está mal, pero con todo esto no podríamos más que buscar cadenas concretas de caracteres, lo que no nos daría la flexibilidad que buscamos, y que recordemos era poder describir patrones abstractos. Por ello, vamos a ver ahora las clases.

Clases

Las clases son un grupo de caracteres con los que incluir más casos de coincidencia —o de excepción— dentro de una expresión regular. Se indican entre corchetes ([]).

Hay varios tipos:

Además, las clases se pueden combinar entre sí simplemente apilándolas unas junto a otras. [\s2-7a-c] seleccionaría cualquier espacio en blanco, las cifras de 2 a 7 y las letras «a», «b» y «c».

Para familiarizarse con las clases lo mejor es aplicarlas, aunque para ver su funcionamiento de una forma rápida y ahorrar picar código en este momento, he creado un comparador de textos y expresiones regulares, en el que voy a someter a la cadena abbcCcddDDeEeffg1 234 a unas cuantas expresiones regulares aplicando match(). Recojo aquí los resultados —el usuario puede repetir las pruebas o probar con sus propias cadenas y sus propias expresiones regulares—:

Como vemos, en todas las expresiones regulares he tenido que especificar todos y cada uno de los caracteres que he querido que match() buscase. Para añadir potencia a las expresiones regulares, también podemos indicar el número de veces que uno de tales caracteres puede repetirse, pero eso lo veremos ya en la continuación de este artículo.

Notas

  1. Como pequeño apunte erudito, la sintaxis y la funcionalidad de las expresiones regulares se recogen en la sección 15.10 del estándar ECMA-262 (inglés), y están basadas en la sintaxis y funcionalidad de Perl 5. Volver
  2. Hay muchas páginas con la tabla de caracteres ASCII; a mí me gusta ésta, aunque lamento que la página no sea válida. Volver
  3. The Unicode Character Code Charts By Script (inglés). Volver
  4. Los códigos de control (inglés) corresponden a caracteres no impresos, como por ejemplo un salto de línea. Volver

Contacto

En virtud de la Ley Orgánica 15/1999 de Protección de Datos de Carácter Personal le informo de que los datos que proporcione no serán empleados para otro fin que el de responder a su mensaje. En especial, me comprometo a no cederlos a terceros ni a emplearlos para enviar información no solicitada.

Del blog de Digital Icon