Nota: Escribí este texto sobre expresiones regulares en 1999, y lo rescaté, actualicé y publiqué en mi web en 2002 gracias a Xosé Manoel Ramos, que lo había conservado en su página web. Gracias, Xosé.
Una expresión regular sirve para comprobar si una cadena coincide con un patrón.
La unidad básica de la expresión regular es el átomo; varios átomos puestos
uno detrás del otro forman una concatenación de átomos, que también es una
expresión regular, pero no un átomo a menos que se ponga entre paréntesis
[()
].
La forma más básica de átomo es un solo carácter, que coincide consigo mismo;
una concatenación de átomos coincide con un patrón más grande ;-). Algunos
caracteres tienen significado especial; para evitar ese significado especial
se preceden con una barra invertida (\
).
Si se introduce una lista de caracteres entre corchetes, eso coincide con
cualquier carácter que esté entre los corchetes, por ejemplo, con la expresión
regular ‘fa[cM]a
’ coinciden ‘faca
’ y ‘faMa
’, pero no ‘faba
’ o ‘fama
’
(se distingue entre mayúsculas y minúsculas). Si el primer carácter entre los
corchetes es un circunflejo (^
) el significado cambia: en ese caso lo
que coincide es cualquier carácter que no esté entre corchetes; con la
expresión regular ‘fa[^cM]a
’ coinciden ‘faba
’ y ‘fama
’, pero no ‘faca
’
y ‘faMa
’. Entre los corchetes se pueden poner rangos de caracteres, por
ejemplo, la expresión ‘fa[c-m]a
’ coincide con ‘faca
’, ‘fada
’, ‘faea
’,
‘fafa
’, …, y ‘fama
’, pero no con ‘faaa
’, ‘faba
’, ‘fana
’, ‘faoa
’,
‘fa9a
’, etc…
El punto (.
) coincide con cualquier carácter, de esta forma, las
palabras ‘fama
’, ‘faba
’ y ‘faca
’ coinciden con la expresión regular
‘fa.a
’; pero no coinciden, por ejemplo, ‘cama
’ o ‘foca
’.
El circunflejo (^
) coincide con el principio de una linea, y el dólar
($
) coincide con el final de la linea; el ‘menor que’ precedido de una
barra invertida (\<
) coincide con el principio de una palabra, y el
‘mayor que’ precedido de barra invertida (\>
) con el final de la
palabra; \b
coincide con una separación entre palabras. Así, con la
expresión regular ‘^fama$
’ coincide ‘fama
’ pero no ‘la fama
’ o ‘fama cuesta
’.
Se puede indicar que un átomo se repite poniendo detrás de él uno de los siguientes modificadores:
El asterisco (*
) indica que el átomo se repite cero o más veces (por
ejemplo, la expresión ‘fa.*a
’ coincide con ‘faa
’, ‘fama
’, ‘faca
’,
‘favela
’, ‘faeliejfelifejlfeijeflija
’, etc, o la expresión ‘do(re)*mi
’
coincide con ‘domi
’, ‘doremi
’, ‘doreremi
’, …)
El signo de adición (+
) indica que el átomo se repite una o más veces
(por ejemplo, la expresión ‘fa.+a
’ coincide con las mismas cadenas que
‘fa.*a
’ excepto ‘faa
’, o la expresión ‘do(re)+mi
’ coincide con las
mismas que ‘do(re*)mi
’ salvo ‘domi
’).
El signo de interrogación (?
) indica que el átomo aparece o no aparece,
pero no se repite (por ejemplo, la expresión ‘fam?a
’ coincide con ‘faa
’ y
‘fama
’, pero no con ‘famma
’ o ‘faba
’, o la expresión ‘do(re)?mi
’
coincide con ‘domi
’ y con ‘doremi
’).
Se puede poner uno o dos números entre llaves, lo que significa que (lo explico mediante ejemplos directamente):
go{2}l
’ - la ‘o
’ coincide exactamente 2 veces (con ‘gool
’)go{2,}l
’ - la ‘o
’ coincide 2 o más veces (con ‘gool
’, ‘goool
’, ‘gooool
’, …)go{,4}l
’ - la ‘o
’ coincide de 0 a 4 veces (’gl
’, ‘gol
’, ‘gool
’, ‘goool
’ y ‘gooool
’)go{2,4}l
’ - la ‘o
’ coincide de 2 a 4 veces (’gool
’, ‘goool
’, ‘gooool
’)Bien, ahora varias formas de concatenar expresiones regulares:
go+l
’ y de ‘del .*
’ forma la expresión regular ‘go+l del .*
’ que es muy util en retransmisiones deportivas ;-)|
) [algunos la verán partida, otros entera] y significa que coincide una de las dos expresiones regulares que se concatenan (ejemplo: ‘del compostela|del real madrid
’ coincide con ‘del compostela
’ y con ‘del real madrid
’ pero no con ‘del barcelona
’ :D)Y, por último, queda algo bastante interesante. Si aparece un número del 1 al
9 precedido por una barra inversa (\
), coincide con una subexpresión
encerrada entre paréntesis precedidos también por barras inversas. Pongo un
ejemplo:
La expresión regular ‘Tengo un \(.*\)\. Me encanta mi \1.
’ coincide con, por
ejemplo, ‘Tengo un PC. Me encanta mi PC.
’ pero no con ‘Tengo un PC. Me encanta mi Mac.
’ Esto es porque \1
coincide con lo mismo que la primera
subexpresión entre \(
y \)
).
Otra expresión regular podría ser ‘\(a\)\(b\)\2\1
’, que sólo coincide con
‘abba
’; el \2
coincide con lo mismo que la segunda subexpresión
encerrada entre \(
y \)
, y el \1
con lo mismo que la
primera.
Y antes de terminar, decir dos cosas: las expresiones regulares suelen
encerrarse entre barras inclinadas (/
); las he puesto aquí entre
comillas para no añadir todavía más confusión :D y las expresiones regulares
pueden probarse con egrep
; en ese caso ponedlas entre comillas como aquí, y
especificad la expresión en la linea de comandos; luego tecleáis cosas que
querráis comprobar, y si os la repite, es que ha coincidido, y si no… pues
no ha coincidido :D
[jtarrio@elvin ~]$ grep '\(a\)\(b\)\2\1'
abba
abba
abcd