• Publicidad

Sustitución y unless

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

Sustitución y unless

Notapor sisifo80 » 2013-11-20 07:40 @361

Buenos días,

Necesito editar un texto de tal forma que elimine toda cadena de caracteres que aparezca entre corchetes, a excepción de ciertas cadenas. Por ejemplo, imaginemos el siguiente texto:

Hola, [yo estoy empezando] a manejar perl, y [todavía no] tengo muchos conocimientos [sobre el tema]

Imaginemos que quiero obtener este mismo texto pero sin las frases que aparezcan entre corchetes, salvo que esas frases incluyan las palabras "no" o "el". Es decir, debería obtener lo siguiente:

Hola, a manejar perl, y [todavía no] tengo muchos conocimientos [sobre el tema]

Mi propuesta es la siguiente, pero no me funciona:

open F, shift;
while(<F>) {
s/\[(.*?)\]//g unless $1 =~ "no" | "el";
print;
}
close F;

La idea sería: sustituir toda cadena de caracteres incluida entre corchetes por cero (es decir, eliminarla), a no ser que esa cadena contenga las subcadenas "no" o "el".

¿Algún consejo?

Gracias anticipadas
sisifo80
Perlero nuevo
Perlero nuevo
 
Mensajes: 32
Registrado: 2013-11-20 07:30 @354

Publicidad

Re: Sustitución y unless

Notapor explorer » 2013-11-20 16:09 @714

Bienvenido a los foros de Perl en Español, sisifo80.

No se puede realizar el problema según lo planteas, porque, lo primero que se ejecuta en la línea es la condición del "unless", y claro, $1 no tiene ningún valor, por lo que la condición siempre falla, y por lo tanto, la sustitución se realiza a lo largo de toda la línea.

He estado buscando algún patrón que haga la tarea, pero no lo he encontrado. Pero sí he encontrado una solución para el problema, alargando un poco la expresión regular:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open F, shift;
  2. while(<F>) {
  3.     s{                                        # realizar sustituciones
  4.         (                                     # primero capturamos
  5.             \s*                               # cero o más espacios
  6.             \[ .*? \]                         # un conjunto de caracteres encerrado entre corchetes
  7.             \s*                               # con cero o más espacios al final
  8.         )                                     # todo eso, lo guardamos en $1
  9.     }                                         # si hemos encontrado todo esto,
  10.     {                                         # lo cambiamos por lo siguiente:
  11.         my $x = $1;                           # guardamos $1 en la variable temporal $x
  12.         $x !~ /\b(?:no|el)\b/                 # si lo capturado antes no contiene una palabra "no" ni "el"
  13.            ? " "                              # devuelve " ", si no,
  14.            : $x;                              # devuelve lo capturado (es decir, no hace nada)
  15.     }gex;
  16.  
  17.     print;
  18. }
  19. close F;
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

Las líneas 3 a 15 se pueden reducir a esta:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     s{(\s*\[.*?\]\s*)}{my $x = $1;$x !~ /\b(?:no|el)\b/ ? " " : $x}ge;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Sigo pensando que puede haber algún patrón que lo haga de forma más sencilla...
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Sustitución y unless

Notapor sisifo80 » 2013-11-21 02:55 @163

Muchas gracias, explorer. No solo por la solución, sino por tu explicación paso a paso, que resulta francamente útil.
sisifo80
Perlero nuevo
Perlero nuevo
 
Mensajes: 32
Registrado: 2013-11-20 07:30 @354

Re: Sustitución y unless

Notapor explorer » 2013-11-23 19:59 @874

Esta es otra forma, más sencilla:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use v5.10;
  3.  
  4. my $texto = "Hola, [yo estoy empezando] a manejar Perl, y [todavía no] tengo muchos conocimientos [sobre el tema].\n";
  5.  
  6. while ($texto =~ m/ \s* \[ .+? \] \s* /gx) {       # localizar lo que nos interesa
  7.     my $encontrado = ${^MATCH};                    # esto es lo que hemos encontrado
  8.     my($pos_ini, $pos_fin) = ($-[0], $+[0]);       # posiciones de lo encontrado
  9.  
  10.     next if $encontrado =~ /\b(?:no|el)\b/;        # repetimos la búsqueda si lo $encontrado coincide con lo que no queremos
  11.  
  12.     substr $texto, $pos_ini, $pos_fin - $pos_ini, ' ';       # cambiamos el $texto, por un solo espacio en blanco
  13.  
  14.     pos($texto) = $pos_ini;                        # ajustamos la posición de la siguiente búsqueda
  15. }
  16.  
  17. say "[$texto]";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Más información en tu propio ordenador en perldoc perlvar, y en la Web (traducido al español).
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 10 invitados

cron