Home Map Index Search News Archives Links About LF
[Top Bar]
[Bottom Bar]
[Photo of the Author]
Guido Socher
Acerca del Author: Le gusta Linux porque es un sistema libre y se diverierte trabajando con gente de la comunidad Linux de todo el mundo. Pasa su tiempo libre con su novia, escuchando la radio de la BBC World Service, montando en bicicleta por el monte y disfrutando con Linux.

Escribe al autor

�ndice de contenidos:
Introducci�n
Un peque�o ejemplo
Reglas de sintaxis
Expresiones regulares para la edici�n de textos

Expresiones Regulares

[Illustration]

Resumen: Las expresiones regulares se utilizan para hacer b�squedas contextuales y modificaciones sobre textos. Se pueden encontrar en muchos editores de textos avanzados, en programas de an�lisis gramatical y en muchos lenguajes.




Introducci�n

Las Expresiones Regulares se pueden encontrar en muchos editores como vi, emacs, en programas como grep, egrep y en lenguajes de programaci�n como awk, perl y sed.

Las Expresiones Regulares se usan para busquedas avanzadas dependientes del contexto. Por eso se puede decir que las Expresiones Regulares no s�lo son un buscador de cadenas de texto, sino que son la descripci�n formal de un patr�n de texto.

Cuando vi por primera vez c�mo se pod�an editar textos con ayuda de Expresiones Regulares, me qued� fascinado. Modificaciones en un texto, para las que hubiese necesitado horas, quedaban listas en pocos segundos. Lo que sin embargo ve�a en el monitor, parec�a un conjunto de puntos, rayas y otros s�mbolos. Sin embargo algo ten�a claro: Quer�a aprender el lenguaje de las Expresiones Regulares y me qued� impresionado de lo f�cil que era de entender. Sigue unas cuantas reglas de sintaxis muy sencillas.

A pesar de que las Expresiones Regulares est�n muy extendidas por el mundo de Unix, no existe un lenguaje est�ndar de Expresiones Regulares. M�s bien se puede hablar de diferentes dialectos. Existen por ejemplo dos representantes del conocido programa grep, egrep y grep. Ambos usan Expresiones Regulares con capacidades ligeramente diferentes. Perl se puede calificar como el lenguaje con la sintaxis de Expresiones Regulares m�s desarrollado. Por suerte todos estos dialectos siguen los mismos principios y en el momento que se han entendido, el resto es sencillo.

En este art�culo me dedicar� �nicamente a los principios b�sicos, los detalles se pueden consultar en las man-pages.

Un peque�o ejemplo

Supongamos que tenemos la siguiente lista de tel�fonos de una empresa:

Phone Name  ID
     ...
     ...
3412    Bob 123
3834  Jonny 333
1248   Kate 634
1423   Tony 567
2567  Peter 435
3567  Alice 535
1548  Kerry 534
     ...

Se trata de una empresa con 500 personas y los datos est�n almacenados en un fichero ASCII normal. Los registros de personas cuyo tel�fono comience con un 1, trabajan en el edificio 1. ¿Qui�n trabaja en el edificio 1?

Una Expresi�n Regular puede responder a eso:

grep '^1' phonelist.txt
o
egrep '^1' phonelist.txt
o
perl -ne 'print if (/^1/)' phonelist.txt

En palabras normales, esto significa: Busca todas las l�neas que comiencen con un 1. El s�mbolo "^" es el encargado de indicar que s�lo se busquen los n�meros 1 que se encuentren al principio de la l�nea.

Reglas de sintaxis

Patr�n de un solo s�mbolo

El elemento b�sico de una expresi�n regular es el patr�n de un solo s�mbolo. �ste patr�n s�lo es efectivo cuando este s�mbolo se puede encontrar exactamente en el texto. Un ejemplo lo podemos encontrar en el n�mero 1 del ejemplo de arriba.

Otro ejemplo para el patr�n de un solo s�mbolo es:

egrep 'Kerry' phonelist.txt

Este patr�n se compone de patrones de un solo s�mbolo (la letra K, e, etc.)

Varios signos se pueden agrupar en un conjunto. Un conjunto se representa por un par de corchetes (el de abrir y el de cerrar) y una lista de caracteres entre ellos. Un conjunto se considera tambi�n como un patr�n de un solo s�mbolo. La b�squeda de este conjunto es efectiva cuando se encuentre uno y solo uno de los signos del conjunto en el texto. Un ejemplo:

[abc] Un patr�n de un solo s�mbolo con el que se puede encontrar el s�mbolo a, b o c.
[ab0-9] Un patr�n de un solo s�mbolo en el que se busca una a o una b o un n�mero que se encuentre entre el 0 y el 9 en el c�digo ASCII.
[a-zA-Z0-9\-] Esto busca una letra may�scula o min�scula o un n�mero o el signo -.
En la lista de tel�fonos:

egrep '^1[348]' phonelist.txt

Esta expresi�n busca l�neas, que comiencen con 13, 14 o 18.

La mayor�a de s�mbolos ASCII nos llevan a una b�squeda exitosa cuando se encuentran en el texto, pero tambi�n encontramos s�mbolos en una expresi�n regular, que tienen un significado especial. Los corchetes hacia la derecha indican el comienzo de la definici�n de un conjunto. El s�mbolo "-" en un conjunto es un s�mbolo especial y representa un rango en el sistema de s�mbolos ASCII. Para indicar que nos referimos al significado normal del s�mbolo, se coloca una barra invertida delante "\". Por ejemplo, en [a-zA-Z0-9\-]. En algunos dialectos encontramos que la barra invertida junto con otro s�mbolo tienen un significado especial. En este caso se obtiene el significado normal retirando la barra invertida.

El punto tambi�n es un s�mbolo importante un una expresi�n regular. La b�squeda ser� efectiva, cuando el s�mbolo comparado sea cualquier s�mbolo menos el s�mbolo de nueva l�nea del c�digo ASCII. Ejemplo:

grep '^.2' phonelist.txt

Esta expresi�n busca l�neas que contengan el n�mero 2 en la segunda posici�n, y cualquier otro s�mbolo delante.

Los conjuntos se pueden invertir mediante la colocaci�n de "[^" en lugar de "[" en la expresi�n. En este caso el s�mbolo "^" no representa el comienzo de la l�nea, sino que "[" y "^" juntos representan el inverso del conjunto.

[0-9] Un patr�n de un solo s�mbolo, la b�squeda ser� efectiva, si el s�mbolo en el texto es un n�mero.
[^0-9] Todo lo que no sea un n�mero.
[^abc] Todo lo que no sea una a, b o c. · Todo menos el s�mbolo de l�nea nueva. Es id�ntico a [^\n]. \n es el s�mbolo para nueva l�nea.

Para buscar todas las l�neas que NO comiencen con un 1, se escribir�a:

egrep '^[^1]' phonelist.txt

Anclas (anchors)

Antes hemos visto que "^" representaba el inicio de una l�nea. Las anclas son s�mbolos especiales en las expresiones regulares, que no denotan un s�mbolo, sino una posici�n.

^   Inicio de una l�nea
$   Final de una l�nea

Para encontrar personas en nuestra lista con un identificativo (company-ID) de 567, utilizaremos la expresi�n:

egrep '567$' phonelist.txt

Significa: Busca l�neas que finalicen con 567.

Multiplicadores

Los multiplicadores nos indican, cuantas veces ha de aparecer un patr�n de un solo s�mbolo en el texto:

Descripci�ngrepegrepperlvivimvileelvisemacs
cero o m�s veces********
una o m�s veces\{1,\}++   \+\+\++
cero o una vez\???   \=\?\=?
de n hasta m veces\{n,m\}   {n,m}       \{n,m\}\{n,m\}

Nota: Para los distintos VI tendr�a que utilizarse la opci�n magic.

Un ejemplo de la lista de tel�fonos:

....
1248   Kate 634
....
1548  Kerry 534
....

Para encontrar una l�nea que se componga de un 1, varios n�meros, varios espacios y la letra K se escribir�:

grep '^1[0-9]\{1,\} \{1,\}K' phonelist.txt
o se utiliza * y se repite [0-9] y el espacio:
grep '^1[0-9][0-9]*  *K' phonelist.txt
o
egrep '^1[0-9]+ +K' phonelist.txt
o
perl -ne 'print if (/^1[0-9]+ +K/)' phonelist.txt

Los multiplicadores nos indican, cuantas veces tiene que aparecer el patr�n de un solo s�mbolo que les precede. "23*4" NO significa "2, 3, quiz�s algo y despu�s un 4" (¡esto ser�a "23.*4"!), sino que significa, que se est� buscando "un 2, quiz�s algunos treses y un 4".

Es importante saber que un multiplicador es �vido. Esto significa que el primer multiplicador se extender� lo m�ximo que pueda hacia la derecha.

Esto no es muy importante en grep, pero es importante en el momento de editar textos.

La expresi�n ^1.*4 se extender�a por toda la l�nea 1548 Kerry 534 de principio a fin.

La expresi�n no se extiende s�lo hasta la zona corta, o sea, 154, sino hasta el m�ximo que se pueda.

Par�ntesis como memoria

Los par�ntesis como memoria no influyen en el tipo o s�mbolos por los que se buscar�. Sirven para que los fragmentos de texto se almacenen y pueda accederse a ellos a trav�s de variables.

El primer par�ntesis ser� referenciado como variable 1, el segundo como variable 2, etc.

Nombre del programaSintaxis del per�ntesisSintaxis de las variables
grep\(\)\1
egrep()\1
perl()\1 or ${1}
vi,vim,vile,elvis\(\)\1
emacs\(\)\1

Un ejemplo: La expresi�n [a-z] [a-z] busca dos letras min�sculas.

Ahora se pueden utilizar estas variables, para buscar patrones de texto como ?otto?:

egrep '([a-z])([a-z])\2\1'
La variable \1 contiene la letra o y \2 la letra t. La expresi�n servir�a tambi�n para anna, pero no para yxyx.

Los par�ntesis no se utilizan normalmente para la b�squeda de nombres como otto y anna, sino que para editar o para buscar y sustituir.

Uso de Expresiones Regulares para el tratamiento de Textos

Para editar textos es necesario un editor de textos como vi o emacs o perl. Todos estos programas soportan expresiones regulares.

En emacs se utiliza M-x query-replace-regexp o replace-regexp. M-x query-replace-regexp pide confirmaci�n en cada b�squeda y sustituci�n. Lo m�s recomendable es asignar a una tecla de funci�n el query-replace o replace-regexp.

En vi se utiliza :%s/ / /gc. El s�mbolo % representa la expresi�n "todo el fichero" por lo que se puede reemplazar por cualquier otra expresi�n. En el editor vim, por ejemplo, se puede marcar una regi�n con may�scula-v y cursor arriba/abajo. Desgraciadamente el art�culo se saldr�a de sus prop�sitos si di�semos una peque�a introducci�n sobre vim. ///gc es interactivo y pregunta por una confirmaci�n. s///g no es interactivo. En perl utilizamos:

perl -pe 's/ / /g'

Ahora unos cuantos ejemplos. En la empresa tienen que modificarse algunos tel�fonos. Todos los tel�fonos que comiencen con un 1, han de tener un 2 despu�s de la segunda cifra. De 1423 pasaremos a 14223.

Phone Name  ID
    ...
3412    Bob 123
3834  Jonny 333
1248   Kate 634
1423   Tony 567
2567  Peter 435
3567  Alice 535
1548  Kerry 534
     ...

y esto es as� de f�cil:

vi:    s/^\(1.\)/\12/g
emacs: ^\(1.\)   sustituir por  \12
perl:  perl -pe 's/^(1.)/${1}2/g' phonelist.txt

La lista de tel�fonos aparecer� as�:

Phone Name  ID
   ...
3412    Bob 123
3834  Jonny 333
12248  Kate 634
14223  Tony 567
2567  Peter 435
3567  Alice 535
15248 Kerry 534
     ...

Perl no s�lo conoce las variables \1 \9. \12 apuntar�a a la variable 12. Para solucionar el problema se utiliza simplemente ${1}.

Pero ahora ya no se encuentran las columnas bien alineadas. ¿C�mo se podr�a solucionar esto? Se podr�a comprobar si hay un espacio en la quinta posici�n e insertar otro.

vi:    s/^\(....\) /\1  /g   
emacs: '^\(....\) '   sustituir por   '\1  ' 
perl:  perl -pe 's/^(....) /${1}  /g' phonelist.txt

Ahora tenemos:

Phone Name  ID
    ...
3412     Bob 123
3834   Jonny 333
12248   Kate 634
14223   Tony 567
2567   Peter 435
3567   Alice 535
15248  Karry 534
    ...

Un colega ha editado la phonelist.txt y no ha tenido cuidado. Al principio de alguna l�nea encontramos espacios. ¿C�mo se puede solucionar?

Phone Name ID
    ...
3412     Bob 123
3834   Jonny 333
12248   Kate 634
14223   Tony 567
2567   Peter 435
3567   Alice 535
15248  Kerry 534
     
    ...

Esto tendr�a que solucionar el problema:

vi:    s/^  *// (dos espacios, pues no tenemos el +)
emacs: '^ +'  sustituir por la cadena vac�a
perl:  perl -pe 's/^ +//' phonelist.txt

Est�s escribiendo un programa y utilizas las variables temp y temporary. Ahora quieres sustituir la variable temp por la variable counter. Si utilizases la opci�n de buscar y reemplazar, ver�as que la variable temporary se reemplazar�a por counterorary. Esto lo quieres evitar.

Las expresiones regulares lo hacen muy f�cil. Se sustituye temp([^o]) con counter\1. Con esto se sustituye temp y no o. (Otra alternativa ser�an las Boundaries, que no se comentaron aqu�.)

Espero que este art�culo te haya despertado la curiosidad. Ahora tendr�as que mirar en las man-pages de t� editor preferido.

Existen m�s s�mbolos especiales en las expresiones regulares, como por ejemplo, Alterations, Art Order, y naturalmente las Boundaries.

Que disfrut�is


Traducido por Franz Jimeno


P�ginas web mantenidas por Miguel �ngel Sep�lveda
© Guido Socher 1998
LinuxFocus 1998