• Publicidad

Obtener un patrón que incluye \n

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

Obtener un patrón que incluye \n

Notapor bartoldo » 2006-04-01 17:44 @780

Hola, estuve leyendo los manuales, pero no sé cómo resolverlo.

Debo reconocer un patrón que puede abarcar más de una línea del archivo ASCII que leo, y sustituirlo por algo 'abc'.

Ejemplo: reconocer las líneas que comiencen con "Aqui" y terminen con "."

El contenido del archivo puede ser el siguiente:
  • Aquí cualquier cosa. Sigue otra "oración...aksldjflkñasjdfklñj.\n"
  • Aquí la línea ocupa tres líneas, este renglón, y "\n"
  • este siguiente y "\n"
  • este otro también, "\n"
O sea, el patrón está dos veces, pero la última vez que ocurre es entre las líneas 2 y 4.

No he podido resolverlo usando expresiones regulares. Tengo problemas para que me reconozca el punto, aun cuando el patrón se encuentra en una misma línea. Este es el código:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.                     $patron = '(\s*\.*)';
  2.                     while (<INFILE>) {
  3.                         if (s/^Aqui$patron./abc/sm) { print; }
  4.  
  5.                     }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Gracias por cualquier sugerencia, saludos.
bartoldo
Perlero nuevo
Perlero nuevo
 
Mensajes: 7
Registrado: 2006-04-01 17:18 @763

Publicidad

Re: obtener un patrón que incluye \n

Notapor explorer » 2006-04-02 05:43 @280

El problema está en leer el fichero línea a línea.

Al leer una línea no tenemos la seguridad de que dentro de ella se encuentre el patrón entero que estamos buscando.

Tenemos dos soluciones:

O leemos el fichero entero a una variable escalar y a continuación hacemos un

$fichero =~ s/^Aquí.+?\./abc/gsm;

con lo que estamos buscando todas las líneas que empiezan (^) por Aquí seguidas por una serie de caracteres (un carácter (.) seguido por uno o más (+)) hasta el primer (?) punto (\.), y lo sustituimos por abc. Esto lo hacemos para una variable escalar con múltiples líneas (/m), incluidos los finales de línea (/s) y para todas las ocasiones (/g).

O, la otra solución, que consiste en leer línea por línea y llevar un control de lo que va ocurriendo. Por ejemplo.
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Para todo el texto, leemos una línea cada vez
  Si la bandera está a 1 (estamos dentro de un patrón detectado)
    Si la línea tiene el final del patrón
      Ponemos la bandera a 0 y
      Hacemos la sustitución, la pintamos y seguimos con la siguiente línea
    Seguimos con la siguiente línea (aún seguimos dentro del patrón detectado)
  Si la línea contiene el comienzo y final del patrón,
    Hacemos la sustitución, la pintamos y seguimos con la siguiente línea
  Si la línea contiene el comienzo del patrón
    Ponemos la bandera a 1 (estamos dentro de un patrón pero no sabemos cuándo terminará) y
    Seguimos con la siguiente línea
  Si no ocurre nada de lo anterior, pintamos la línea tal cual
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
Es natural que la primera solución (una línea) sea mejor... :)

En tu caso:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $patron = '(\s*\.*)';
  2. while (<INFILE>) {
  3.     if (s/^Aqui$patron./abc/sm) {
  4.         print;
  5.     }
  6. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Lo que haces es: Para todas las líneas del fichero (while), si (if) la línea puede realizar una sustitución del patrón, la pintamos (print), siendo el patrón a buscar: ^Aqui\s*\.*., que significa: la línea empieza (^) por Aqui, seguido de 0 o más espacios en blanco (\s*), seguidos de 0 o más puntos (\.*) y seguidos por un carácter cualquiera (.), para todas las líneas (/m) leídas (aunque me parece que sólo hemos leído una).
Última edición por explorer el 2006-04-02 06:03 @294, editado 3 veces en total
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

Notapor preiddy » 2006-04-02 05:44 @280

explorer me dió una solución a un problema parecido al tuyo, quizás te sirva:

while ( $base =~ /(^PT.+?^ER *?$)/smg )

Con esta expresión se le dice principio y fin de campos, independientemente de cuántos saltos de línea tenga.
preiddy
Perlero nuevo
Perlero nuevo
 
Mensajes: 70
Registrado: 2006-03-29 05:43 @280
Ubicación: Madrid, España

Notapor bartoldo » 2006-04-02 12:55 @579

Gente: voy a probar las sugerencias, luego les cuento. Gracias
bartoldo
Perlero nuevo
Perlero nuevo
 
Mensajes: 7
Registrado: 2006-04-01 17:18 @763

Notapor bartoldo » 2006-04-02 13:22 @598

Bueno, el problema parece ser que no me reconoce el patrón, que recuerdo es toda frase que comience con la palabra "Aquí" y termina con ".", donde el "." no tiene por qué estar antes de un "\n", puede estar en el medio de una línea.

Ejemplo: "Aquí estamos. Sin nada que hacer\n", la frase debería quedar:
abc Sin nada que hacer\n

Probé
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. while ( $file =~ /^Aqui.*?\./smg ) {
  2.     print if s/^Aqui.*?\./abc/smg;
  3. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Olímpicamente ignora el patrón.

Seguidamente probé la otra sugerencia:

$file =~ s/^Aqui.*?\./abc/smg; # ignoró también, no hubo cambios

Creo que el tema está en reconocer el ".", porque si no lo considero en el patrón, encuentra las frases, solo que no sustituye lo que quiero.

Seguiré intentando, desde ya les agradezco cualquier idea.
Saludos.
bartoldo
Perlero nuevo
Perlero nuevo
 
Mensajes: 7
Registrado: 2006-04-01 17:18 @763

Re: obtener un patrón que incluye \n

Notapor explorer » 2006-04-02 13:32 @605

Supongamos que el fichero kk.txt sea
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Aquí cualquier cosa. Sigue otra oraciónaksldjflkñasjdfklñj.
Aquí la línea ocupa tres (3) lineas, este renglón,
este siguiente y
este otro también.
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Entonces, con el programa
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. open FILE, "<kk.txt";
  3. while ( $linea = <FILE> ) {
  4.   $fichero = $fichero . $linea;   # Leemos todas las líneas y las metemos en una variable
  5. }
  6. close FILE;
  7. $fichero =~ s/^Aqui.+?\./abc/gsm; # Transmutación, ¡Aquí y Ahora!
  8. print $fichero;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
sale
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
abc Sigue otra oraciónaksldjflkñasjdfklñj.
abc
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
¿No es eso lo que tiene que salir?
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

Notapor bartoldo » 2006-04-02 20:14 @885

Es exactamente eso, funciona, gracias :)
bartoldo
Perlero nuevo
Perlero nuevo
 
Mensajes: 7
Registrado: 2006-04-01 17:18 @763


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron