La expresiones regulares (ER) son una forma de describir cadenas
de caracteres. Se usan en operaciones de apareamiento o comparación.
Las expresiones regulares permiten realizar búsquedas o
sustituciones de gran complejidad.
Las búsquedas en el editor vi
con los comandos / y ? aceptan expresiones regulares; esto hace las
búsquedas mucho más potentes y flexibles. Las expresiones regulares
son aceptadas en otros editores y en muchos comandos, si bien con
algunas diferencias de sintaxis.
Una expresión regular es un
patrón que describe un conjunto de cadenas de caracteres. Por
ejemplo, el patrón aba*.txt describe el conjunto de cadenas
de caracteres que comienzan con aba, contienen cualquier
otro grupo de caracteres, luego un punto, y finalmente la cadena txt.
El símbolo * se interpreta como "0, 1 o más caracteres
cualesquiera".
Las expresiones regulares se construyen como
las expresiones aritméticas, usando operadores para combinar
expresiones más pequeñas. Analizaremos esos operadores y las reglas
de construcción de expresiones regulares, atendiendo siempre al
conjunto de cadenas que representa cada patrón.
La construcción de expresiones regulares depende de la asignación de significado especial a algunos caracteres. En el patrón aba*.txt el caracter * no vale por sí mismo, como el caracter asterisco, sino que indica un "conjunto de caracteres cualesquiera". Asimismo, el caracter ? no se interpreta como el signo de interrogación sino que representa "un caracter cualquiera y uno solo". Estos caracteres a los que se asigna significado especial se denominan "metacaracteres".
El conjunto de metacaracteres para expresiones regulares es el siguiente:
\ ^ $ . [ ] { } | ( ) * + ?
Estos caracteres, en una expresión regular, son interpretados en su significado especial y no como los caracteres que normalmente representan. Una búsqueda que implique alguno de estos caracteres obligará a "escaparlo" de la interpretación mediante \, como se hace para evitar la interpretación por el shell de los metacaracteres del shell. En una expresión regular, el caracter ? representa "un caracter cualquiera"; si escribimos \?, estamos representando el caracter ? tal cual, sin significado adicional.
Una expresión regular determina un conjunto de cadenas de caracteres. Un miembro de este conjunto de cadenas se dice que aparea, equipara o satisface la expresión regular.
Las expresiones regulares se componen
de expresiones regulares elementales que aparean con un único
caracter:
|
|
|
|
|
|
|
|
|
|
|
|
\e |
|
Los paréntesis rectos [] delimitan listas de caracteres
individuales. Muchos metacaracteres pierden su significado si están
dentro de listas: los caracteres especiales . * [ \ valen
por sí dentro de []. Para incluir un caracter ] en
una lista, colocarlo al principio; para incluir un ^
colocarlo en cualquier lugar menos al principio; para incluir un -
colocarlo al final.
Dentro de los conjuntos de caracteres
individuales, se reconocen las siguientes categorías:
[:alnum:] alfanuméricos
[:alpha:]
alfabéticos
[:cntrl:] de control
[:digit:] dígitos
[:graph:]
gráficos
[:lower:] minúsculas
[:print:] imprimibles
[:punct:]
de puntuación
[:space:] espacios
[:upper:] mayúsculas
[:xdigit:]
dígitos hexadecimales
Por ejemplo, [[:alnum:]] significa [0-9A-Za-z], pero esta última expresión depende de la secuencia de codificación ASCII, en cambio la primera es portable, no pierde su significado bajo distintas codificaciones. En los nombres de categorías, los paréntesis rectos forman parte del nombre de la categoría, no pueden ser omitidos.
Una Expresión Regular se contruye con
uno o más operadores que indican, cada uno, el caracter a buscar.
Los operadores más comunes y aceptados son los siguientes:
Operador |
Significado |
c |
un caracter no especial concuerda consigo mismo |
\c |
elimina significado especial de un caracter c; el \ escapa el significado especial |
^ |
indica ubicado al comienzo de la línea (cadena nula al principio de línea) |
$ |
indica ubicado al final de la línea (cadena nula al final de línea) |
. |
(punto) un caracter individual cualquiera |
[...] |
uno cualquiera de los caracteres ...; acepta intervalos del tipo a-z, 0-9, A-Z (lista) |
[^...] |
un caracter distinto de ... ; acepta intervalos del tipo a-z, 0-9, A-Z |
r* |
0, 1 o más ocurrencias de la ER r (repetición) |
r1r2 |
la ER r1 seguida de la ER r2 (concatenación) |
Las expresiones regulares se aprenden
mejor con los ejemplos y el uso.
Exp.Reg. |
aparea con |
a.b |
axb aab abb aSb a#b ... |
a..b |
axxb aaab abbb a4$b ... |
[abc] |
a b c (cadenas de un caracter) |
[aA] |
a A (cadenas de un caracter) |
[aA][bB] |
ab Ab aB AB (cadenas de dos caracteres) |
[0123456789] |
0 1 2 3 4 5 6 7 8 9 |
[0-9] |
0 1 2 3 4 5 6 7 8 9 |
[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 completa |
Algunos comandos, como egrep o
grep -E, aceptan Expresiones Regulares Extendidas, que
comprenden las Expresiones Regulares Básicas más algunos operadores
que permiten construcciones más complejas. Los operadores
incorporados son los siguientes:
Operador |
Significado |
r+ |
1 o más ocurrencias de la ER r |
r? |
0 o una ocurrencia de la ER r, y no más |
r{n} |
n ocurrencias de la ER r |
r{n,} |
n o más ocurrencias de la ER r |
r{,m} |
0 o a lo sumo m ocurrencias de la ER r |
r{n,m} |
n o más ocurrencias de la ER r, pero a lo sumo m |
r1|r2 |
la ER r1 o la ER r2 (alternativa) |
(r) |
ER anidada |
"r" |
evita que los caracteres de la ER r sean interpretados por el shell |
La repetición tiene precedencia sobre la concatenación; la concatenación tiene precedencia sobre la alternativa. Una expresión puede encerrarse entre paréntesis para ser evaluada primero.
Exp.Reg.Ext. |
aparea con |
|
|
|
|
|
|
|
|
|
|
|
|
En GNU, no se distinguen expresiones regulares básicas de
extendidas; los comandos aceptan todas las expresiones regulares. En
ese caso, como siempre se están usando extendidas, los
metacaracteres ?, +, {, |, (, y ) deben ser escapados cuando se
quieren usar como caracteres normales, escribiendo \?, \+, \{, \|,
\(, y \).
Referencias:
Kernighan-Pike[1987], Coffin[1989]