Next Previous Contents

5. Tratamiento de cadenas

5.1 Reconocimiento de patrones

En Perl no sólo se puede comprobar si una cadena es igual, mayor o menor a otra; el uso más habitual es usar reconocimiento de patrones ("pattern matching", en inglés), por el cual se comprueba si una cadena "encaja" dentro de un marco que se indica en forma de expresión regular.

Las expresiones regulares son, simplemente, formas de indicar estos patrones. Se componen de átomos que se pueden combinar para formar expresiones complejas. Se irán explicando a medida que se vayan viendo.

La forma más sencilla de ver esto es con un ejemplo:



$a=<STDIN>;

if ($a =~ /hola/) {
        print "Hola a ti también";
}
elsif ($a =~ /adios/) {
        print "Adios";
}

El significado de esto es bastante evidente: si la cadena $a contiene la palabra "hola", se imprime "Hola a ti también"; si contiene "adios", se imprime "Adios".

El signo se usa para indicar que la variable dada debe encajar dentro del patrón expresado entre las dos barras. Si quisiéramos indicar que la variable no debe encajar, usaríamos .

La potencia de esta herramienta viene dada por la potencia de las expresiones regulares. Con ellas podemos realizar comparaciones más complejas (y útiles), como ésta:


if ($a =~ /^A.*B$/) {
        # Actuar
}

La expresión entre ambas barras significa: "Una línea que empiece por 'A' y termine en 'B'". El acento circunflejo ("^") simboliza el principio de línea; la letra 'A' se representa a sí misma; el punto (".") significa "cualquier carácter", y el asterisco ("*") significa "el carácter anterior repetido cualquier número de veces"; la 'B' se representa a sí misma, como la 'A', y el símbolo del dólar ("$") simboliza el fin de la línea.

Otro ejemplo:


if ($a !~ /^(A|B)/) {
        # Actuar
}

En este caso, el if se evaluará a "cierto" cuando la variable $a no coincida con la expresión regular indicada (por usar , en lugar de ). Esta expresión significa "Las líneas que empiecen por 'A' o por 'B'". La barra vertical ("|") simboliza un "or" lógico entre las expresiones que tiene a ambos lados. Para agrupar expresiones usamos los paréntesis, como en cualquier otro lenguaje.

Un último ejemplo:


if ($a =~ /[ABC]+$/) {
        # Actuar
}

En este caso, la expresión regular significa "Las líneas que terminen en 'A', 'B' o 'C'". Los corchetes hacen algo así como un "or" lógico entre todos los caracteres que se incluyen en su interior. La expresión [ABC] se evalúa a cierta cuando cualquiera de estos caracteres está presente. El signo de sumar que viene después especifica la cantidad de veces que debe aparecer ese caracter; si no se pone un "cuantificador" como éste (y el asterisco, que se veía antes), se supone que el carácter debe aparecer sólo una vez; el signo de sumar indica "Uno o más de los caracteres anteriores". Aquí se usa con una expresión entre corchetes, pero evidentemente se podría usar con cualquier caracter normal o especial (como 'A', o el punto, por ejemplo).

Las expresiones regulares suelen confundir bastante al principio, y además explicarlas completamente se escapa del ámbito de esta introducción. Sólo se dan unas pinceladas para que no "suenen a chino" luego.

5.2 Sustituciones

Una de las herramientas clásicas que Perl "asimila" es sed. Esta herramienta sirve para hacer sustituciones en cadenas de texto; y como no podía ser de otra forma, usa expresiones regulares.

En Perl se usa con el operador s/:


$a = "Hola hola";

$a =~ s/o/0/g;
$a =~ s/a/4/g;

En este ejemplo se vuelve a usar el operador que se usaba en el reconocimiento de patrones, ; sin embargo, en este caso no está sirviendo para una comparación, sino para una asignación. Como tantas cosas en Perl, todo depende del contexto. Lo que haría es simplemente cambiar cualquier "o" que apareciera en la cadena $a por un "0". La "g" que aparece al final indica que esta sustitución se debe hacer en todas las ocurrencias de la cadena. Luego se hace otra sustitución parecida, "a" por "4". El resultado del ejemplo sería que la cadena $a pasaría de contener "Hola hola" a contener "H0l4 h0l4".

Podemos hacer cosas más complicadas, por supuesto:


$a =~ s/[Hh][Oo][Ll][Aa]/hola/g;

Esto sustituiría cualquier posible combinación de mayúsculas y minúsculas para la palabra "hola" por una versión en minúsculas. Es algo sin utilidad porque existen las funciones uc("upper case") y lc("lower case") que devuelven una versión en mayúsculas o minúsculas, respectivamente, de la cadena que se les pase. Pero como ejemplo está bien.


Next Previous Contents