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.
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.
= '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/;
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/;
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 ...
ayuda de los cuantificadores. Los cuantificadores permiten especificar como los componentes de una expresión pueden aparecer en la cadena de búsqueda. =
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;
$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
= 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;
= 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)
----- ^ ^ ^ ^ | | | | 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'
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, ...)
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
\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
= 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
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]/;
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 ' ó '
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
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/[!\-?]/;
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
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;
my $domain = qr/@(?<dom>.+)/; my $email = qr/$name$domain/; say $+{dom} if $string =~ $email; say $+{name} if $string =~ $email; > barcelonapm.org > info
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}
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)+/;
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
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
' 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;
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.
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'
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) '
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.
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.
"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.
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.
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;
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.
~~ $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