Expresiones regulares en PERL

Las expresiones regulares son una suerte de lenguaje interno al perl, pero no sólo (por ejemplo se encuntran en comandos como grep, sed awk). En cualquier caso, no hay 2 programas que tengan que ver con las expresiones regulares y las interpreten del mismo modo.

Una expresión regular está entre / , aunque se trata más bien de una convención que de una regla. Resulta normal ver una expresión regular entre | o # o cualquier otro carácter, para evitar que aparezca el símbolo \ delante de todos los / en regexp.

 

Una expresión regular define un pattern que será buscado. En las expresiones regulares, los caracteres alfanuméricos (de la a a la z, de la A a la Z, de 0 a 9 y _ ) tienen una correspondencia unívoca, mientras que otros caracteres tienen características especiales.

 

Un \ seguido por un carácter no alfanumérico corresponde exactamente a ese carácter; en concreto, \\ corresponde a \ .

 

^ — (sólo al inicio de la expresión) hace que el texto corresponda al pattern sólo si el pattern está al comienzo del texto.

 

$ — (sólo al final de la expresión) hace que el texto corresponda al pattern sólo si el pattern está al final del texto.

 

Algún ejemplo aclarará un poco las cosas.

 

«bla» =~ /\//

falso, ya que busca en «bla» el carácter /

 

«blh» =~ /\$/

falso, ya que busca en «bla» el carácter £

 

Por eso para buscar un carácter especial (o, si se quiere, reservado) hay que aclararlo a través del símbolo \ que se está buscando exactamente ese carácter y no su valor. Y lo mismo para la búsqueda con grep, y también con editor (vi, por ejemplo)

 

«bla» =~ /la/ verdadero

«bla» =~ /^la/ falso

«bla» =~ /^bl/ verdadero

«bla» =~ /h$/ verdadero

«bla» =~ /ls$/ falso

«bla» =~ /^bla$/ verdadero

 

Otros caracteres especiales son:

. — busca cada carácter individual

\t — busca una tabulación

\s — busca un espacio o una tabulación

\S — busca todo carácter que no sea una tabulación

\n — busca una «newline»

\w — busca toda letra concreta, cifra y también _

\W — busca todo lo que no sea una letra, una cifra o _

\d — busca toda cifra individual de 0 a 9

\D — busca todo carácter que no sea una cifra

 

«bla» =~ /b.a/ verdadero

«bla» =~ /b.la/ falso

«bla» =~ /b\w.h$/ verdadero

«bla» =~ /\w\D/ vero

«bla» =~ /\d/ falso

 

[caracteres] — busca todo carácter que esté entre [ ]

 

Además, un campo de búsqueda se puede especificar con – , por ejemplo [a-m] busca las letras entre la a y la m.

Si el primer carácter entre [ ] es ^ , al significado se le da la vuelta, y se buscará todo lo que NO está comprendido entre [ ]

 

[-.0.9] busca exactamente un – un . o una cifra

 

[^\@ \t] busca cualquier carácter que no sea un @, una tabulación o un espacio. Hay que señalar que \ delante de @ es opcional, ya que el símbolo @ no tiene significados particulares en este contexto, pero funciona también con \@

 

Cuantificadores:

determinan el número mínimo y máximo de veces que un determinado elemento tiene que repetirse consecutivamente:

 

( ) — reagrupa más elementos en un pattern que se debe buscar una vez

* — Corresponde al intervalo {0, } o bien de un mínimo de 0 veces a un máximo indefinido

+ — Corresponde al intervalo {1, }

? — Corresponde al intervalo {0, 1}

s — Opera una sustitución

tr — Opera una traducción en la forma ‘tr [a-z] [A-Z]’ (o bien convierte en mayúsculas los caracteres que están en minúscula y viceversa)

 

«bla» =~ /c*k*z?b+.l/ verdadero, dado que la c, la k y la z no están, la b aparece una vez y la l también

 

«ccckkzbbb8lZOINX» =~ /c*k*z?b+.l/ vedadero «blabla» =~ /ah(EEK)?bl/ verdadero «blaEEKbla» =~ /ah(EEK)?bl/ verdadero «blaEEKEEKbla» =~ /ah(EEK)?bl/ falso «blaEEKEEKbla» =~ /ah(EEK)+bl/ vero

 

/^([^\@ \t]+\@[^\@ \t])+\s+([-.0-9]+)$/

 

El último ejemplo corresponde a una línea que empieza con un número distinto de 0 de caracteres que no son ni @ ni espacios ni tabulaciones, después una @, luego otros caracteres que no son @ ni espacios ni tabulaciones, después algunos espacios y tabulaciones, luego cualquier mezcla de ‘-‘, ‘.’ y cifra. Dicho vulgarmente, algo parecido a una dirección e-mail seguido de espacios y ¡algo que se puede pensar razonablemente como un número! En palabras aún más vulgares, una vez que se entiende cómo funcionan las expresiones regulares, resulta más fácil escribirlas que explicarlas.

 

/^\s*(\d+)\.(\d+)\.(\d+)\.(\d+)\s*$/

 

Esto, sin embargo, podría corresponderse con una dirección IP.

Además, si el pattern tiene sub-pattern (), éstos se asignan a variables numeradas, $1 para la primera, $2 para la segunda, etc.

 

«129.199.129.13» =~ /^\s*(\d+)\.(\d+)\.(\d+)\.(\d+)\s*$/;

$1 è 129, $2 è 199, $3 è 129, $4 è 13

 

Un pattern con sustitución se escribe de la forma:

 

$variable =~ s/pattern/replacement/;

 

El pattern es, como antes, una expresión regular, y el replacement es una cadena normal, excepto por el hecho de que las variables están interpoladas en su interior.

En la mayor parte de los casos, se puede añadir el carácter ‘g’ después del replacement, de manera que se cambien todas las palabras que corresponden al pattern, y no sólo la primera.

 

$waitops{$c} =~ s/:${oldnick}:/:${newnick}:/g

 

Las expresiones regulares trabajan con la función split, que toma como argumento una expresión regular, una variable escalar y, si se quiere, un segundo escalar que especifica el número máximo de campos en que splittare el pattern.

 

@array = split(/pattern/, expression);

 

En el caso más típico, se puede querer splittare una línea en palabras, como sigue:

 

@words = split(/\s+/, $some_line); # si $some_line era «a b c», ahora

@words es («a», «b», «c»)

 

o bien

 

($val1, $val2) = split(/\s+/, $whatever); # setta $val1 con el primero

valor de $whatever y $val2 con el segundo. Otros valores eventuales (tercero, cuarto, etc.) son descartados