expresiones regulares

Post on 12-Jun-2015

1.245 Views

Category:

Documents

2 Downloads

Preview:

Click to see full reader

DESCRIPTION

Dentro del marco del Curso 2011 de Introducción a Perl realizado por el grupo Barcelona.pm

TRANSCRIPT

EXPRESIONES REGULARES

   

Barcelona.pm(CC) 2011

por cjuan

 Curso de Introducción de Perl

¿Qué es un Regex?

La potencia de Perl en el procesamiento de textos viene dado por las expresiones regulares.

Una expresión regular es un patrón que describe las características de un trozo de texto.

Una expresión regular interpreta los patrones y los aplica para modificar o buscar coincidencias en un texto.

¿Qué es un Regex?

Ejemplo del poder del Regex:Tenemos el ADN de una rana

... GATAAACCCAGGTTTAGATACAAAA ...

¿Qué es un Regex?

... GATAAACCCAGGTTTAGATACAAAA ...

podemos buscar un trozo de la cadena de ADN y substituirla por otra cadena.

s/GATACA/ATACA/

consiguiendo la nueva secuencia de ADN:

... GATAAACCCAGGTTTAATACAAAA ...

¿Qué es un Regex?

... GATAAACCCAGGTTTAATACAAAA ...

Patrones Simples

Buscar un patrón en una cadena:my $name = 'Modern Perl';say $name if $name =~ m/Perl/;                                                                                              ¿'Modern Perl' contiene 'Perl'? entonces devuelve '1'  > Moderl Perl eropero no es lo mismo si $name vale 'Pelr'     say $name if $name !~ m/Pelr/;

Patrones Simples

Es lo mismo: 

$name =~ m/Perl/;    <==>    $name =~ /Perl/;  

m/<patrón>/   <==>    /<patrón>/   

Patrones Simples

Substituir una cadena:my $name = 'Barroque Perl';$name =~ s/Barroque/Modern/; say $name; 

ero

Patrones Simples

Substituir una cadena:my $name = 'Barroque Perl';$name =~ s/Barroque/Modern/; say $name;  > Modern Perlero

El comando qr// y combinaciones

El comando qr/<patrón>/ permite crear clases de carácteres que podemos combinar en la misma expresión.         

El comando qr// y combinaciones

El comando qr/<patrón>/ permite crear clases de carácteres que podemos combinar en la misma expresión.          my $phrase = 'Esto es Modern Perl ...';         my $string1 = qr/Modern/;    my $string2 = qr/Perl/;

    say 'Eureka!! '.$phrase if $phrase =~ /$string1 $string2/;

El comando qr// y combinaciones

El comando qr/<patrón>/ permite crear clases de carácteres que podemos combinar en la misma expresión.          my $phrase = 'Esto es Modern Perl ...';         my $string1 = qr/Modern/;    my $string2 = qr/Perl/;

    say 'Eureka!! '.$phrase if $phrase =~ /$string1 $string2/;

    > Eureka!! Esto es Modern Perl ...

Cuantificadores

Las expresiones regulares alcanzan una nueva dimensión con la ayuda de los cuantificadores. Los cuantificadores permiten especificar como los componentes de una expresión pueden aparecer en la cadena de búsqueda.   =

Cuantificadores

?    => 0 ó 1 aparición m/ca?t/;

iif ($string =~ m/ca?t/) {  say 'puede ser ct o cat';}

Cuantificadores

?    => 0 ó 1 aparición m/ca?t/;  +    => 1 ó más apariciones m/ca+t/;   

iif ($string =~ m/ca+t/) {  say 'puede ser cat o caaat';}

Cuantificadores

?    => 0 ó 1 aparición m/ca?t/;  +    => 1 ó más apariciones m/ca+t/;    *    => 0 ó más apariciones m/ca*t/;

iif ($string =~ m/ca*t/) {  say 'puede ser ct, cat o caaat';}

Cuantificadores Numéricos

{n} => 'n' apariciones m/ca{1}t/

iif ($string =~ m/ca{1}t/) {  say 'exactamente cat';}

Cuantificadores Numéricos

{n} => 'n' apariciones m/ca{1}t/ {n, }    => 'n' ó más   m/ca{1, }t/;   

iif ($string =~ m/ca{1, }t/) {  say 'puede ser cat, caat, caaaa......at';}

Cuantificadores Numéricos

{n} => 'n' apariciones m/ca{1}t/ {n, }    => 'n' ó más   m/ca{1, }t/;   {n,m}    => entre 'n' y 'm' m/ca{1,3}t/; 

iif ($string =~ m/ca{1,3}t/) {  say 'puede ser cat, caat o caaat';}

Cuantificadores Posesivos

+    }  Los cuantificadores posesivos son traicioneros !!* Es decir, encuentran más de lo que deben.  Ejemplo:my $string_1 = 'la casa es grande y fria';my $search = qr/casa.*gran/;   

Cuantificadores Posesivos

Ejemplo:my $string_1 = 'la casa es grande y fria';my $search = qr/casa.*gran/;  1) /casa/ hace una búsqueda del patrón2) /.*/ busca 0 ó más carácteres3) /gran/ busca un patrón definido

Cuantificadores Posesivos

my $string_1 = 'la casa es grande y fria';my $string_2 = 'casada y gran madre';

my $search = qr/casa.*gran/;

say 'encontre \'casa\' y \'gran\' en '.$string_1     if $string_1 =~ $search;say 'encontre \'casa\' y \'gran\' en '.$string_2     if $string_2 =~ $search;

Cuantificadores Posesivos

my $string_1 = 'la casa es grande';my $string_2 = 'casada y gran madre';

my $search = qr/casa.*gran/;

say 'encontre \'casa\' y \'gran\' en '.$string_1     if $string_1 =~ $search;say 'encontre \'casa\' y \'gran\' en '.$string_2     if $string_2 =~ $search; > encontre 'casa' y 'gran' en la casa es grande> encontre 'casa' y 'gran' en casada y gran madre

Anclajes

\A => indica que la comparación debe ser en el principio del string.

\Z => indica que debe buscar el match al final de la linea dentro del string.  

Anclajes

my $string = 'la URL es http://barcelonapm.wordpress.com';my $search = qr/\A(barcelonapm).*/;say $1 if $string =~ $search;

my $fichero = 'dupa.png';my $search_ext = qr/(.*)\.(png)\Z/;say 'mi archivo '.$2.' es '.$1 if $fichero =~ $search_ext; 

Anclajes

my $string = 'la URL es http://barcelonapm.wordpress.com';my $search = qr/\A(barcelonapm).*/;say $1 if $string =~ $search;

my $fichero = 'archivo: dupa.png';my $search_ext = qr/(.*)\.(png)\Z/;say 'mi archivo '.$2.' es '.$1 if $fichero =~ $search_ext; > (nada)    (... el string no comienza con 'barcelonapm') > mi archivo png es dupa    (hace la comparación desde el final)

Anclajes de palabras

Esto   es   Modern   Perl                                 -----    --    ---------    -----                                    ^       ^         ^           ^                                     |        |          |            |                   Palabra     1      2        3           4

Con el metacaracter \b<palabra>\b podemos asegurar que  encontraremos 'saca' y no 'casacamiento'La contra será \B. qr/\bcasa.*?\b/;Encontrara 'casa' y 'casamiento' pero no 'encasado'                            

Anclajes de palabras

my $string = 'la URL es http://barcelonapm.wordpress.com';my $search = qr/\b(barcelona.+?)\b/;say $1 if $string =~ $search;

Anclajes de palabras

my $string = 'la URL es http://barcelonapm.wordpress.com';my $search = qr/\b(barcelona.+?)\b/;say $1 if $string =~ $search;

> barcelonapm 

Anclajes de palabras

my $string = 'la URL es http://barcelonapm.wordpress.com';my $search = qr/\b(barcelona.+?)\b/;say $1 if $string =~ $search;

> barcelonapm El límite de \b está entre un carácter de palabra y otro de no-palabra. En este caso el punto (.) entre barcelonapm y wordpress.

Las palabras son secuencias de letras, dígitos y '_'(barcelonapm, wordpress, com, ...)

Anclajes de palabras

my $string = 'la URL es http://barcelonapm.wordpress.com';my $search = qr/\b(barcelona.+?)\b/;say $1 if $string =~ $search;

> barcelonapm 

El mismo ejemplo sin los metacarácteres \b nos sale:

my $search = qr/(barcelona.+?)/;> barcelonap

Metacarácteres

Son carácteres especiales en las regex que son interpretados de manera diferente a un literal.

Esto ofrece muchas posibilidades al no depender solo de las subcadenas.

Metacarácteres. 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

Metacarácteres

my $phone = '93 234 43 56';my $prefix = qr/\A(\d{2})\s(.+)/;say 'Prefijo: '.$1.' número: '.$2 if $phone =~ $prefix;  \d{2} --> busca 2 carácteres numéricos\s      --> busca un espacio en blanco.+      --> cualquier carácter 1 ó más veces

Metacarácteres

my $phone = '93 234 43 56';my $prefix = qr/\A(\d{2})\s(.+)/;say 'Prefijo: '.$1.' número: '.$2 if $phone =~ $prefix;   > Prefijo: 93 número: 234 43 56

Metacarácteres

my $string = 'Si todos los derechos son reservados¿son todos los zurdos muy habladores?'; my $search = qr/(\n.*)/;

say $1 if $string =~ $search;

(después de la palabra reservados hay una nueva linea)

Metacarácteres

my $string = 'Si todos los derechos son reservados¿son todos los zurdos muy habladores?'; my $search = qr/(\n.*)/;

say $1 if $string =~ $search;> ¿son todos los zurdos muy habladores?

Clases de carácteres

Cuando ninguno de los metacarácteresse ajusta a nuestro patrón podemos crear nuestras clases de carácteres.

Para especificar una clase de carácter lo encerramos entre corchetes [ ]

Clases de carácteres

Cuando ninguno de los metacarácteresse ajusta a nuestro patrón podemos crear nuestras clases de carácteres.

Para especificar una clase de carácter lo encerramos entre corchetes [ ]

Por ejemplo:my $vocals = qr/[aeiou]/;my $pares = qr/[2468]/;

Clases de carácteres

my $string = '1 ó 2 pajaritos en la fuente';my $vocals = qr/([aeiou])/;my $pares = qr/([2468])/;

say 'vocales: '.$1 if $string =~ $vocals;say 'pares: '.$1 if $string =~ $pares;

Clases de carácteres

my $string = '1 ó 2 pajaritos en la fuente';my $vocals = qr/([aeiou])/;my $pares = qr/([2468])/;

say 'vocales: '.$1 if $string =~ $vocals;say 'pares: '.$1 if $string =~ $pares;

> vocales: a> pares: 2 Se muestra la primera vocal que encuentraNo hemos tenido en cuenta la ' ó '

Clases de carácteres

Podemos crear un rango continuo de carácteres en la clase mediante el guión ' - '

my $letters = qr/[a-zA-Z]/;

en este caso se buscará coincidencias de cualquier letra ya sea mayúscula o minúscula.

Lo mismo podemos hacer con los números:

    my $numbers = qr/[0-9]/;

es decir, 0, 1, 2, 3, 4, 5, 6, 7, 8 y 9

Clases de carácteres

Si queremos utilizar el guión como carácter de búsqueda debemos situarlo al principio o al final del patrón:

my $signos = qr/[-!?]/;my $signos = qr/[!?-]/; o bien escapar el carácter:my $signos = qr/[!\-?]/;

Clases de carácteres

Para buscar todo menos la clase de caracteres añadimos ^ al principio:

    my $pares = qr/[^2468]/;  o sea, todos los números que no sean pares

Capturando datos

Las regex permiten capturar y agrupar porciones de las búsquedas para su uso posterior.

Para ello agrupamos la porción de datos entre paréntesis ()

    my $data = qr/(.+)\s(.+)/;    say $1.' '.$2;

la captura se almacena en variables mágicas:    $1 hace referencia al primer grupo    $2 al segundo grupo

Capturando datos

La captura mediante nombres se añade a partir de perl 5.10

my $string = 'info@barcelonapm.org';

my $name = qr/\A(?<name>\w+[^@])/;my $domain = qr/@(?<dom>.+)/;my $email = qr/$name$domain/;

say $+{dom} if $string =~ $email;say $+{name} if $string =~ $email; 

Capturando datos

my $string = 'info@barcelonapm.org';

my $name = qr/\A(?<name>\w+[^@])/;my $domain = qr/@(?<dom>.+)/;my $email = qr/$name$domain/;

say $+{dom} if $string =~ $email;say $+{name} if $string =~ $email; > barcelonapm.org> info 

Capturando datos

La captura de datos mediante nombre sigue la siguiente sintaxis:

    (?<nombre captura> ... regex ...) Cuando se cumple una expresión, perl almacena en la variable mágica %+ los datos conseguidos.

En este hash la clave es el nombre de la captura y el valor los datos conseguidos.

    $+{nombre_captura} 

Agrupación y Alternación

Podemos agrupar partes de un patrón mediante paréntesis ()

    qr/perl+/;     <-- puede encontrar perl, perlita, perlero, ...    qr/(perl)+/;  <-- encontrará perl

El patrón agrupado dentro de la expresión es almacenado en un grupo de captura (parecido a un buffer) y podemos reutilizarla en la expresión mediante \1, \2, etc :

    qr/(perl)+\1/; <==> qr/(perl)+(perl)+/;

Agrupación y Alternación

En algunos casos necesitamos que se busque una u otra cosaPara ello usamos el metacaracter ' | '

    qr/Carlos|Alex|Frankie/;

La comparación será positiva si encuentra cualquiera de los 3 nombres.

    qr/(Modern|Barroque)+Perl/;

será válido para las cadenas    Modern Perl    Barroque Perl

Agrupación y Alternación

Para reducir los riesgos de confusión en las capturas de datos podemos utilizar la secuéncia ' ?: ' que indica que el grupo no es capturable      qr/(?:Modern|Barroque)+Perl/; en este caso $1 no tiene valor

Condiciones

Usamos la secuencia ' ?= ' o ' ?! ' para indicar una condición en el patrón de búsqueda.

    my $string_1 = 'catastrofe';

    my $cond_1 = qr/cat(?!astrofe)/;    my $cond_2 = qr/cat(?=.)/;

    say 'oh no!!!' if $string_1 =~ $cond_1;    say 'found a cat' if $string_2 =~ $cond_2;

Condiciones

    my $cond_1 = qr/cat(?!astrofe)/;    my $cond_2 = qr/cat(?=.)/;

    > found a cat

$cond_1 indica que 'cat' no puede ser seguida por 'astrofe', por lo que 'catastrofe' es una palabra que no queremos

$cond_2 busca una palabra que empieza por 'cat' y seguida por 0 ó cualquier carácter

Las condiciones deben tener un tamaño fijo, no se deben utilizar cuantificadores.

Modificadores

Los modificadores cambian el comportamiento de los operadores de las expresiones regulares.

Estos modificadores aparecen al final del match, substitucion o qr//

Por ejemplo, para ignorar entre mayúsculas y minúsculas usamos el modificador ' /i '

    qr=/Perl/i; <== encuentra 'Perl' y 'perl'

Modificadores

Se pueden añadir los modificadores en medio de la regex mediante la sentencia ' (?i) ', pero solo para agrupamientos.

    qr=/Modern ((?i)perl)/;

Encontrará tanto 'Modern Perl' como 'Moden perl'

Mientras que /i modifica toda la regex, (?i) solo un grupo

Para desactivar un modificador precedente usamos ' (?-i) '

Modificadores

Otros modificadores:

/m   Trata a la cadena como múltiples líneas. Es decir, cambia "^" y "$" de coincidir con el principio y final de cadena para coincidir con el principio y final de cualquier línea dentro de la cadena.

/s   Trata la cadena como una sola línea. Es decir, cambia "." para que coteje con cualquier carácter, incluso el fin de línea, que normalmente no lo haría.

Modificadores

Usados juntos, como /ms, hacen que "." coincida con cualquier carácter, mientras que "^" y "$" coincidan, respectivamente, con justo después y justo antes de los caracteres nueva línea, dentro de la cadena.

Modificadores

/i   Hace cotejamientos independientes del tamaño de caja.

Si "use locale" está activo, el tamaño de caja se toma del locale actual. Ver perllocale.

/x   Extiende la legibilidad de su patrón permitiendo espacios en blanco y comentarios.

/p   Preserva la cadena cotejada en ${^PREMATCH}, ${^MATCH}, y ${^POSTMATCH}, estando disponibles para ser usados después del cotejo.

Modificadores

/g y c  Coincidencia global, y mantenimiento de la posición actual después de un cotejamiento fallido.  A diferencia de i, m, s y x, estas dos opciones afectan la forma en que la regex es usada, en lugar de a la propio expresión regular.

Coincidencias Inteligentes

El operador inteligente ' ~~ ' compara dos operadores y devuelve verdadero si se encuentra una en la otra.

Por ejemplo:

    my $x = 10;    my $y = 20;    say 'no es igual' unless $x ~~ $y;

    my $x = 10;    my $y = '10 puntos';    say 'numeros coinciden' if $x ~~ $y;

Coincidencias Inteligentes

El tipo de comparación depende primero del tipo de operador de la derecha. Si el operador de la derecha es escalar con un componente numérico la comparación usará una igualdad numérica. Si el operador de la derecha es un array, la comparación realizará un grep Si el operador de la derecha es un hash, la comparación buscará la existencia de una o más claves.

Coincidencias Inteligentes

my $needlepat = qr/needle/;

say 'Pattern match'if $needle ~~ $needlepat;say 'Grep through array' if @haystack ~~ $needlepat;say 'Grep through hash keys' if %hayhash ~~ $needlepat;

say 'Grep through array'if $needlepat ~~ @haystack;say 'Array elements exist as hash keys'if %hayhash ~~ @haystack;say 'Array elements smart match'if @strawstack ~~ @haystack;

say 'Grep through hash keys'if $needlepat ~~ %hayhash;say 'Array elements exist as hash keys' if @haystack ~~ %hayhach;say 'Hash keys identical'if %hayhash ~~ %haymap;

más información en perldoc perlsyn

Documentación sobre regex

Disponemos de una gran fuente de información en perldoc: • perldoc perlretut  => Perl Regular Expresions Tutorial• perldoc perlreref => Perl Regular Expresions Reference• perldoc perlre      => Perl Regular Expresions

Preguntas?

 

barcelona-pm(cc) 2011 - cjuan

http://barcelonapm.wordpress.com/

top related