Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Expresiones Regulares en Perl

Expresiones Regulares en Perl

Introducción a las expresiones regulares en Perl. Presentación que estuvo planificada para el Curso de Introducción a Perl, realizado por el grupo Barcelona Perl Mongers en noviembre de 2011.

Avatar for Carlos Juan Diaz

Carlos Juan Diaz

November 05, 2011
Tweet

Other Decks in Programming

Transcript

  1. ¿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.
  2. ¿Qué es un Regex? Ejemplo del poder del Regex: Tenemos

    el ADN de una rana ... GATAAACCCAGGTTTAGATACAAAA ...
  3. ¿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 ...
  4. 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 ero pero no es lo mismo si $name vale 'Pelr' say $name if $name !~ m/Pelr/;
  5. Patrones Simples Es lo mismo: $name =~ m/Perl/; <==> $name

    =~ /Perl/; m/<patrón>/ <==> /<patrón>/
  6. Patrones Simples Substituir una cadena: my $name = 'Barroque Perl';

    $name =~ s/Barroque/Modern/; say $name; ero
  7. Patrones Simples Substituir una cadena: my $name = 'Barroque Perl';

    $name =~ s/Barroque/Modern/; say $name; > Modern Perl ero
  8. El comando qr// y combinaciones El comando qr/<patrón>/ permite crear

    clases de carácteres que podemos combinar en la misma expresión.
  9. 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/;
  10. 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 ...
  11. 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. =
  12. Cuantificadores ? => 0 ó 1 aparición m/ca?t/; iif ($string

    =~ m/ca?t/) { say 'puede ser ct o cat'; }
  13. 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'; }
  14. 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'; }
  15. 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'; }
  16. 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'; }
  17. 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/;
  18. 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ón 2) /.*/ busca 0 ó más carácteres 3) /gran/ busca un patrón definido
  19. 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;
  20. 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
  21. 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.
  22. 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;
  23. 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)
  24. 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'
  25. Anclajes de palabras my $string = 'la URL es http://barcelonapm.wordpress.com';

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

    my $search = qr/\b(barcelona.+?)\b/; say $1 if $string =~ $search; > barcelonapm
  27. 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, ...)
  28. 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
  29. 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.
  30. 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
  31. 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
  32. 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
  33. 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)
  34. 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?
  35. 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 [ ]
  36. 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]/;
  37. 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;
  38. 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 encuentra No hemos tenido en cuenta la ' ó '
  39. 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
  40. 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/[!\-?]/;
  41. 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
  42. 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
  43. Capturando datos La captura mediante nombres se añade a partir

    de perl 5.10 my $string = '[email protected]'; 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;
  44. Capturando datos my $string = '[email protected]'; 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
  45. 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}
  46. 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)+/;
  47. Agrupación y Alternación En algunos casos necesitamos que se busque

    una u otra cosa Para 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
  48. 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
  49. 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;
  50. 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.
  51. 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'
  52. 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) '
  53. 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.
  54. 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.
  55. 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.
  56. 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.
  57. 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;
  58. 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.
  59. 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
  60. 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