Saltar la navegación

Expresiones regulares

Las expresiones regulares sirven para hacer operaciones de buscar o bucar y reemplazar de un forma sofisticada. En Unix, donde casi todo son ficheros de texto, son una herramienta casi imprescindible. No tan solo de cara al administrador, sino también de cara a cualquier usuario o programador.

Imaginemos un cliente que pide una modificación para su página web que nosotros administramos, y quiere que todo lo que hasta ahora era cursiva se vuelva negrita, pero solo si el contenido de la frase usa una palabra clave. Pensemos este problema en Word: buscamos una frase que contenga la palabra "clave", miramos si está entre las etiquetas de cursiva <i></i> y en caso afirmativo, reemplazamos <i></i> por <b></b>. Pues para problemas de este tipo se inventaron las expresiones regulares.

Una expresión regular es un patrón que describe un conjunto de cadenas. Las expresiones regulares se construyen de manera análoga a las expresiones aritméticas, mediante el uso de diversos operadores que combinan expresiones más pequeñas. Los filtros de la familia grep entienden tres sintaxis diferentes de expresiones regulares: básica (BRE), extendida (ERE) y perl (Perl). Nosotros nos vamos a centrar en estos momentos en las dos primeras.

Las expresiones regulares se utilizan en:

  • operaciones de comparación.
  • búsquedas o sustituciones de gran complejidad.

Una expresión regular no es más que una cadena de texto (patrón) en la que distinguimos dos tipos de caracteres:

  • Caracteres ordinarios: Solo concuerdan con ellos mismos.
  • Caracteres especiales: Tienen un significado especial para el programa que los interpreta.

Hay caracteres especiales que tienen un significado especial independientemente del lugar del patrón donde aparezcan (*, [, etc.). Sin embargo, hay otros que solo tienen un significado especial cuando se sitúan en una posición determinada; el carácter ^ es especial si va al comienzo del patrón y el carácter $ solo cuando va al final.

Si queremos usar un carácter especial dentro de una cadena como carácter ordinario deberemos protegerlo, precediéndolo de una barra invertida (\*, \[, \^, \$, etc.).

A continuación vamos a ver todos los caracteres especiales y su significado:

.       El carácter punto concuerda con cualquier carácter excepto con el carácter de fin de línea (\ n).
[lista]  

Los corchetes concuerdan con un único carácter cualquiera de los presentes en la lista o de los ausentes si la lista comienza por el carácter ^. Por ejemplo: [0123456789] coincide con un dígito y [^0123456789] coincide con cualquier carácter que no sea un dígito. Dentro de los corchetes también se puede especificar un rango mediante la colocación de dos caracteres separados por un guión. Por ejemplo, las dos expresiones regulares anteriores son equivalentes a las dos siguientes, respectivamente: [0-9] y [^0-9]. Los dos caracteres que definen el rango deben ir ordenados de menor a mayor, es decir, la expresión regular [9-0] sería incorrecta.

Ciertas listas de caracteres se usan mucho, por lo que ya están creadas y se les ha dado un nombre: [:alnum:], [:alpha:], [:cntrl:], [:digit:], [:graph:], [:lower:], [:print:], [:punct:], [:space:], [:upper:], and [:xdigit:].

Para incluir el ] se debe poner el primero, para el ^ lo pondremos en cualquier sitio menos al principio y para incluir el - lo pondremos el último: Por ejemplo: []^-]

Los rangos y las listas se pueden mezclar: [a[:digit:]x-z^]

R* El carácter asterisco concuerda con cero o más repeticiones de la expresión regular que le precede (R).
^R Solo tiene significado especial cuando es el primer carácter de la expresión regular. Concuerda con el comienzo de la línea, por lo tanto, se estaría diciendo que lo que vaya a continuación del carácter ^ debe estar al principio de la línea para que concuerde el patrón.
R$ Solo tiene un significado especial cuando es el último carácter de la expresión regular. Concuerda con el final de la línea, por lo tanto, se estaría diciendo que lo que esté antes del $ debe estar al final de la línea para que concuerde el patrón.
\<R Solo tiene significado especial cuando es el primer carácter de la expresión regular. Concuerda con el inicio de una palabra.
R\> Solo tiene significado especial cuando es el último carácter de la expresión regular. Concuerda con el final de una palabra.
\bR\b
Solo tiene significado especial cuando es el primer o último carácter de la expresión regular. Concuerda con el inicio o final de una palabra.
\B Es el complementario de \b. Sirve para exigir que un patrón no esté al comienzo, o al final o ni al comienzo ni al final de una palabra.
\w Es equivalente a [_[:alnum:]]
\W Es el complementario de \w. Es equivalente a [^_[:alnum:]]
R1R2 Esto es la concatenación. Dos expresiones regulares pueden concatenarse, la expresión regular resultante concuerda con cualquier cadena formada por la concatenación de dos subcadenas que concuerdan con R1 y R2 respectivamente.

Hasta aquí, los metacaracteres para construir expresiones regulares básicas. Algunos ejemplos son los siguientes:

Patrón Coincide con
a.b aXb aab abb adb a9b ...
a..b aXXb aaab abbb aabb a6;b ...
[abc] a b c
[aA] a A
[aA][bB]   ab Ab aB AB
[A-Za-z] A B C ... Z a b c ... z
[0-9][0-9][0-9]   000 001 ... 009 010 ... 019 100 ... 999
[0-9]* cadena vacía, 0 1 9 00 99 123 456 999 9999 ...
[0-9][0-9]* 0 1 9 00 99 123 456 999 9999 99999 99999999 ...
^.*$ cualquier línea, incluida la vacía.

Las expresiones regulares extendidas pueden hacer uso de los caracteres especiales que forman parte de las expresiones regulares básicas y además de los siguientes metacaracteres:

R+ El signo más concuerda con una o más repeticiones de la expresión regular que le precede (R).
R? El carácter interrogación cerrada concuerda con cero o una aparición de la expresión regular que le precede (R).
R{n} Concuerda con n repeticiones exactas de R.

R{n,}

Concuerda con n o más repeticiones de R.
R{,n} Concuerda con cero o a lo sumo n repeticiones de R.
R{n,m}     Concuerda con al menos n repeticiones de R, o como mucho m repeticiones.
R1|R2 (alternativa) Concuerda con la expresión regular R1 o R2.
(R) Sirve como en las expresiones aritméticas, para alterar las prioridades de los operadores. Lo que tiene más prioridad siempre será lo que esté entre paréntesis.

Los operadores de repetición (*, +, ? y {) tienen mayor prioridad sobre la concatenación, y esta a su vez, tiene mayor prioridad que la alternativa.

En las expresiones regulares extendidas se puede utilizar el operador de referencia \m, donde m es un dígito del 1 al 9. Este operador concuerda con la cadena que casa con la m-ésima expresión regular entre paréntesis, empezando a contar por la izquierda. Por ejemplo, la expresión regular '([0-9]) \1 [0-9]' concuerda con la cadena '8 8 7', pues \1 es la subcadena '8', ya que ([0-9]) casa con '8'. La cadena '8 7 8' no casa con la expresión regular, pues \1 es 8 y aparece en su lugar un 7. Esto es interesante en operaciones de búsqueda y sustitución, pues estos operadores de repetición pueden utilizarse para recuperar parte de la cadena buscada y usarla dentro de la cadena por la que se va a reemplazar.

Ejemplos de expresiones regulares extendidas:

Patrón Coincide con
[0-9]+ 0 1 9 00 99 123 456 999 9999 99999 99999999 ...
[0-9]? cadena vacía, 0 1 2 .. 9
^a|b una a al comienzo de línea ó una b.
(ab)* cadena vacía, ab abab ababab ...
^[0-9]?b b 0b 1b 2b .. 9b, cualquiera de lo anterior pero al comienzo de una línea.    
([0-9]+ab)*   cadena vacía, 1234ab 9ab9ab9ab 99ab957ab ...

 

Licencia: licencia de software libre GPL