• Publicidad

Preservar zonas de una lista a la hora de usar s//

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Preservar zonas de una lista a la hora de usar s//

Notapor pvaldes » 2011-02-11 12:15 @552

Me han surgido un par de dudas relacionadas con el operador =~ s//g;

Supongamos que tengo una lista de términos de longitud variable, cada uno de los cuales consta de un prefijo y un sufijo separados por un carácter determinado, que es lo único común a todos los elementos de la lista.

Imaginemos que tuviera éste aspecto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my @arreglo = ('lanza_rote','for_mentera','i_biza');
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4

donde todo lo que está antes de "_" es el prefijo, y lo que está después el sufijo.

Pues bien, quiero usar el operador de substitución sobre todos los elementos del arreglo, cosa que hago con algo como:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
for my $elem(@arreglo) {$elem=~s/a/e/g ; }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Hasta ahí, nada raro. Sin embargo quiero ejecutar la substitución sólo sobre una parte de cada elemento y preservar la otra, es decir, la idea sería:

Sustituye "a" por "e" pero solamente si está antes de "_".

Mi primera idea fue dividir cada elemento en dos:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my ($prefijo,$sufijo) = split /_/;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

y trabajar sólo sobre el primero, pero al imprimir @arreglo tras la sustitución obtengo:

1327

Es decir, me aplana la lista a un escalar y entonces al aplicar s// lo que obtengo es el número de veces que ocurre la substitución.

Como el número de caracteres y la posición del separador no son constantes no puedo usar substr() tampoco.

Puedo solucionarlo fácilmente con sed, o perl -e o esquivar el problema con otro enfoque (que presenta sus propios problemas) pero me gustaría saber la manera de incluir la solución en mi programa de Perl (seguramente será muy evidente una vez dicho, pero hoy no estoy inspirado, está claro).

Y esa es la primera duda, la segunda, si no cae el fin de semana ya irá en su propio hilo.
pvaldes
Perlero nuevo
Perlero nuevo
 
Mensajes: 129
Registrado: 2011-01-22 12:56 @580

Publicidad

Re: Preservar zonas de una lista a la hora de usar s//

Notapor pvaldes » 2011-02-11 12:33 @565

más intentos: usar split de ésta manera tampoco funciona

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. foreach (my @arreglo){
  2. chomp;
  3. push my @lineas, [split /_/];
  4. }
  5. print "@lineas\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


resultado:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
ARRAY(0x98d45a0) ARRAY(0x98d4740) ARRAY(0x98d47c0)
 
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Al menos he dejado de obtener un número :wink:, entiendo que todo esto son referencias y que cada elemento es ahora un array, ¿voy bien?
pvaldes
Perlero nuevo
Perlero nuevo
 
Mensajes: 129
Registrado: 2011-01-22 12:56 @580

Re: Preservar zonas de una lista a la hora de usar s//

Notapor explorer » 2011-02-11 12:50 @577

Bueno, una solución sencilla es la que comentas: partir, sustituir, recomponer:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. my @arreglo = qw(lanza_rote for_mentera i_biza);
  7.  
  8. for (@arreglo) {
  9.  
  10.     my @partes = split /_/;
  11.     $partes[0] =~ s/a/e/g;
  12.     $_ = join '_', @partes;
  13. }
  14.  
  15. print "@arreglo\n";
  16.  
  17. __END__
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Estoy sospechando que se puede hacer con una sola expresión regular, pero localizar todas las 'a' que están delante de '_', es algo complicado... O es que se me escapa algo...
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Preservar zonas de una lista a la hora de usar s//

Notapor pvaldes » 2011-02-11 13:00 @583

Hacerlo con una expresión regular sería un ejercicio interesante en cualquier caso, pero la solución que das es impecable. Obviamente me estaba liando al usar split().

Muchas gracias.
pvaldes
Perlero nuevo
Perlero nuevo
 
Mensajes: 129
Registrado: 2011-01-22 12:56 @580

Re: Preservar zonas de una lista a la hora de usar s//

Notapor explorer » 2011-02-11 13:19 @596

Encontré la solución:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. my @arreglo = qw(lanza_rote for_mentera i_biza aaaa_aaaa);
  7.  
  8. for (@arreglo) {
  9.     s/\G [^a_]* \K a/e/gx;
  10. }
  11.  
  12. print "@arreglo\n";
  13.  
  14. __END__
  15. lenze_rote for_mentera i_biza eeee_aaaa
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

El funcionamiento de la expresión regular es la siguiente:

«Queremos sustituir todas (/g) las 'a' por 'e', teniendo en cuenta que, desde la última sustitución (\G) hasta la siguiente 'a', no debe existir ninguna 'a' ni '_' ([^a_]*). Todos esos caracteres que preceden a la 'a' a sustituir, no formarán parte de la sustitución (\K)».

La expresión regular empieza buscando las letras 'a' y las va sustituyendo, hasta que encuentra el '_', momento en el cual ya no se puede seguir cumpliendo la regla '\G[_]', por lo que falla y termina la sustitución.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Preservar zonas de una lista a la hora de usar s//

Notapor pvaldes » 2011-02-14 05:27 @268

Interesante :mrgreen:, esta me la apunto. Supongo que podría usarse también $', ahora que lo pienso.
pvaldes
Perlero nuevo
Perlero nuevo
 
Mensajes: 129
Registrado: 2011-01-22 12:56 @580


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: Bing [Bot] y 0 invitados

cron