2. MODELOS DE BUSQUEDA

2.1. Modelos básicos.

Mediante modelos de caracteres podemos explorar archivos y visualizar las ocurrencias de un determinado modelo.

Los modelos se expresan escribiéndolos entre dos barras: /expresión/
Vamos a probar directamente desde la línea de comando...

Ejemplo: Del archivo SALUDO.TXT queremos visualizar las líneas que contengan la palabra "Hola". Teclear:

C:\>PERL -ne "print if /Hola/;" saludo.txt

Resultado:

Hola, Mundo...
Hola Mundo, otra vez.

Ejemplo: Del archivo SALUDO.TXT queremos visualizar las líneas que contengan al menos un punto. Teclear:

C:\>perl -ne "print if /./;" saludo.txt

Resultado:

Hola, Mundo...
...Adios, Mundo.
Hola Mundo, otra vez.
Adios Mundo.

Otros ejemplos: el fichero AVERIAS.TXT nos servirá para utilizar nuevas formas de búsqueda y conocer parte de la potencia de Perl en este tema:

30-12-98 12:00 Antonio López OKI SGE No enciende aloki
30-12-98 12:15 María Sánchez OKI SGT No funciona bien msoki
30-12-98 13:13 Carlos Mena HP SGT No tiene tinta cmhp
30-12-98 13:16 Luis López HP SGE Atasca papel llhp
31-12-98 12:00 Luisa López FUJ SGE No enciende llfuj
31-12-98 12:15 Claudio Sánchez OKI FEDER Instalar Word csoki
31-12-98 14:13 Felipe León OCT SGT No tiene tinta floct
31-12-98 14:25 Gloria Roca FUJ FEDER Instalar Jupiter grfuj
01-01-99 11:00 Luis López HP SGE Atasca papel llhp
01-01-99 11:05 Miguel López HP SGE Atasca papel mlhp

- Extraer las averías de SGE y de SGT.

C:\perl>perl -ne "print if /SG./;" averias.txt

El punto que está después de la G actúa como un comodín Es más lógico poner /SG/ para los datos existentes.

- Extraer las averías de Luis López.

C:\perl>perl -ne "print if /Luis López/;" averias.txt

- Extraer todas las averias de la marca HP.

C:\perl>perl -ne "print if /HP/;" averias.txt

- Extraer todas las averias en que hubo atasco.

C:\perl>perl -ne "print if /ATASC/;" averias.txt

-Usando más comodines:

. = cualquiera excepto el carácter de línea nueva.
+ = uno o más del carácter anterior.
? = Ninguno o uno del carácter anterior.
* = Ninguno o más del carácter anterior.
^ = Busca la coincidencia sólo al comienzo de la línea.
$ = Busca la coincidencia sólo al final de la línea.
# = Esto no es ningún comodín. Se usa para comentarios, los precede.

Si anteponemos \ (barra invertida) a cualquier comodín nos referimos al carácter en concreto.

- Extraer todas las averías con una o más F.

C:\perl>perl -ne "print if /F+/;" averias.txt

Si prueba con f (minúscula) el resultado es distinto.

- Extraer todas las averías de los hermanos Luis y Luisa López.

C:\perl>perl -ne "print if /Luisa*/;" averias.txt

- Extraer todas las averías del día 30-12-98.

C:\perl>perl -ne "print if /30-12/;" averias.txt

- Extraer todas las averías con primera letra del nombre M y final de apellido z.

C:\perl>perl -ne "print if /M.*z/;" averias.txt

(En realidad busca todo lo que empiece por M seguido de uno o más caracteres y con una z como carácter final de la cadena).

- Extraer todas las averías que finalicen en hp.

C:\perl>perl -ne "print if /hp$/;" averias.txt

- Extraer todas las averías que se dieron los días 30 y 31 de diciembre.

C:\perl>perl -ne "print if /^3.-12/;" averias.txt

2.2. Modelos avanzados.

2.2.1. Modelo {Min, Max}.

Se usa para buscar expresiones que se repiten.

Ejemplos:

/N.{1,3}d.*/ # Navidad, Navideño, Nada, Nudo (entre 1 y 3)
/a.{2}r/ # amar, atar, asar (2 caracteres entre a y r).
/al.{5, }/ # altozano, alcantarilla, albaricoque (5 o más).
/(am){2, }.*/ # amamanta, amamantó (am repetido 2 veces o más)

2.2.2. Modelo de clase [aeiou].

Se usa para establecer un rango de caracteres permitidos.

/bar.[aeiou].*/ # barca, barquero, barcelonés, bares, abarcar
/c[ao]../ # cara, cosa, cata, cala, coto, cana, cono
/[0-9]/ # 0,1,2,3,4,5,6,7,8,9
/[A-Z][a-z]/ # Aa, Za, Jk, Lm ...
/[a-zA-Z]/ # a, A, B, J, Z ...
/[A-CJ-L2-5]/ # A, B, C, J, K, L, 2, 3, 4, 5
/[^a-c].*/ # diente, zoo (cualquiera que no empiece por a,b o c)
/SE-[^A-Za-z]{4}-[^0-9]?/ # SE-0001-C, SE-8887-BJ, SE-1100-DA

2.2.3. Modelo de alternativa / | /.

Se usa para indicar opciones alternativas en un módelo de búsqueda.

/No fu|Si ca/ # No fumo, Si canto, No futbol, Si carros
/chicos/chicas/ # llegaron chicos, van chicas, las chicas
/No (fum|ju).*ar/ # No fumigar, No fumar, No jurar, No jugar

2.2.4. Carácteres especiales para modelos.

^ El modelo comienza al principio de la cadena.
$ El modelo termina al final de la cadena.
\r Retroceso de carro, 13 decimal ASCII.
\n Alimentación de línea 10 decimal ASCII en UNIX. 13+10 en DOS
\t Tabulación, TAB, 9 decimal ASCII.
\f Alimentación de página, 12 decimal ASCII.
\d Dígitos. Equivale a [0-9].
\D No dígitos.
\w Alfanumérico [a-zA-Z0-9_] (incluida barra subrayado).
\W No alfanumérico.
\s Espacio en blanco (incluye espacio, \t, \r, \n, \f).
\S Negación de \s. \b Límite ini-fin de palabra; coincide con puntuación, \s o \w.
\B Negación de \b.

Ejemplos:

/^\d+\t/; # comienzo de cadena por uno o más digitos seguidos de tab.
/\D$/; # cualquier cadena que termine en algo que no sean números.

2.2.5. Otros modelos útiles.

2.2.5.1. Modelo =~.

Cambia el objetivo de búsqueda para un modelo.

Ejemplo (cambobje.pl):

# Cambio de objetivos

$_="El cielo es azul"; $objetivo0 = $_;
$objetivo1 = "La casa es blanca";
$objetivo2 = "El perro es grande";
print if /cielo/;
if ($objetivo0 =~/azul/) { print $objetivo0 };
if ($objetivo1 =~/casa/) { print $objetivo1 };
if ($objetivo2 =~/perro/) { print $objetivo2 };

2.2.5.2. Modelo //i.

Ignora diferencia de mayúsculas y minúsculas.

/menú/ # menú y nada más /menú/i # Menú, MENÚ, mENú, menú

2.2.5.3. Modelo s///.

Busca y reemplaza la primera expresión encontrada de una cadena.

Ejemplo (buscmode.pl):

$_="los coches son blancos y blancos";
s/blancos/rojos/;
print; #los coches son rojos y blancos

$_="ahh..ahh..chuss... ¡lo siento!";
s/^ah+/oohh/; #oohh..ahh.. ¡lo siento!
print;

2.2.5.4. Modelo s///g.

Busca y reemplaza toda las expresiones en una cadena.

$_="Navidad, Navidad, dulce Navidad";
s/Navidad/Mesa de camilla/g; print; #Mesa de camilla, Mesa de camilla, dulce Mesa de camilla

2.2.5.5. Modelo tr///.

Intercambia caracteres según la correspondencia de un patrón.

Ejemplo (traslaci.pl):

$_="ten cuidado con la carretera";
tr/aeiou/AEIOU/;
print; # tEn cUIdAdO cOn lA cArrEtErA"

$_="libros+de+ciencia";
tr/\+/ /;
print; #libros de ciencia
tr/ /\+/; print; #libros+de+ciencia

$_="codigo secreto: 0013273";
tr/[0-9]/[a-j]/;
print; #codigo secreto: aabdchd

2.2.5.6. Modelo (Subexpresión) $1 $2...

Se usa para buscar subexpresiones repetidas y permite acortar la escritura de los modelos.

/(expresión1) (expresión2...) $1 $2/;

/Tengo una y(ama) que y$1 se y$1/; #Tengo una yama que yama se llama
/(color)in $1ado/; #colorin colorado
/([A-Z][A-Z]).*$1/; #ABNAB, CC2CC, DD4766jjDD

Ejemplo usando búsqueda y sustitución (expres.pl):

# Subexpresión usada para buscar y reemplazar en una cadena:

$_="nombre edad lugar ";
s/([a-z]+)\s/campo_$1,/g; #campo_nombre,campo_edad,campo_lugar
print;

2.2.5.7. Modelo s///e.

Evalua expresiones y funciones Perl que forman parte de un modelo de búsqueda.

$_ = "banana"; s/an/1+2/e; print; #Imprime: b3ana

$_ = "banana"; s/an/1+2/eg; #Imprime: b33a (la 'g' hace una sustitución global)

$_ = "banana"; s/a/pack("C", hex(41))/eg #Imprime: bAnAnA