• Publicidad

Reconocer y contabilizar caracteres

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

Re: Reconocer y contabilizar caracteres

Notapor koolik » 2012-04-22 23:41 @029

Pues gracias, al menos buscar esas directivas me ha orientado y estoy captando la potencia de este lenguaje.

Lo que no he logrado es que respete los saltos de línea.

Ni los casos como estos:
a
b
que no deben tener los '[]'.

Entrada:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
aab

a
b
ababaabbb
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Salida:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
a[2]b

a
b
ababa[2]b[3]
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4



Sintáxis: [ Descargar ] [ Ocultar ]
  1. while (<>) 
  2. {  
  3.  if ($_ =~ s/((a|b)\2+)(\n\n*)/$2 . '[' . length($1) . ']'/ge) 
  4.  { 
  5.   print $_; 
  6.  } 
  7. }  
koolik
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2012-04-21 17:42 @779

Publicidad

Re: Reconocer y contabilizar caracteres

Notapor koolik » 2012-04-23 00:41 @070

explorer: estoy a un paso, pero no sé si voy por el camino indicado.

Me falta capturar los saltos de línea "\n".

Así captura sin "\n":
Sintáxis: [ Descargar ] [ Ocultar ]
  1. while (<>) 
  2. {  
  3.  if ($_ =~ s/((a|b)\2*)/ if (length ($1) > 1) {$2 . '[' . length($1) . ']'} else {$2}/ge) 
  4.   
  5.  { 
  6.   print $_;     
  7.  } 

Con ese código, funciona así:
Entrada:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
a


babbb
aab

b
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Salida:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
a


ba[3]
a[2]b

b
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Le puse un "\n" a la expresión, pero no funciona:
Sintáxis: [ Descargar ] [ Ocultar ]
  1. while (<>) 
  2. {  
  3.  if ($_ =~ s/((a|b)\2*)(\n\n*)/ if (length ($1) > 1) {$2 . '[' . length($1) . ']'} else {$2}/ge) 
  4.  #if ($_ =~ /((a|b)\2*)/g) 
  5.  { 
  6.   print $_;     
  7.  } 


Gracias por tu ayuda.
koolik
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2012-04-21 17:42 @779

Re: Reconocer y contabilizar caracteres

Notapor explorer » 2012-04-23 11:38 @526

Es mejor dividir el problema...
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/env perl
  2.  
  3. my $lineas_vacias = 0;
  4.  
  5. while (<>) {
  6.     if (/^\s*$/) {                 # si la línea está vacía,
  7.         $linea_vacias++;           # sumamos una más, y
  8.     }
  9.     else {                         # si no, transformación:
  10.         s/((a|b)\2+)/$2 . '[' . length($1) . ']'/ge;
  11.         print;
  12.     }
  13. }
  14.  
  15. print "Número de líneas vacías: $lineas_vacias\n";
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4
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: Reconocer y contabilizar caracteres

Notapor koolik » 2012-04-23 14:52 @661

Gracias como siempre explorer. Con unos pequeños arreglos comenzó a funcionar.

Este es el código final:

Sintáxis: [ Descargar ] [ Ocultar ]
  1. while (<>) 
  2. {  
  3.   
  4.  if ($_ =~ /^(\s|\n)*$/)  
  5.  {  
  6.    print $_  
  7.  }   
  8.  else 
  9.  { 
  10.     s/((0|1)\2*)/ if (length ($1) > 1) {$2 . '<' . length($1) . '>'} else {$2}/ge; 
  11.     print; 
  12.  }  
  13. }  


Cualquier observación, es más que agradecida.
Saludos
koolik
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2012-04-21 17:42 @779

Re: Reconocer y contabilizar caracteres

Notapor explorer » 2012-04-23 15:27 @685

* decías que querías contar las líneas que están en blanco, pero en lugar de eso, solo las sacas en pantalla. Es decir, no haces nada con ellas
* $_ es la variable por defecto, así que no es necesario ponerla en muchas operaciones. Así

if ($_ =~ /^(\s|\n)*$/)

es lo mismo que

if (/^(\s|\n)*$/)

y

print $_;

es lo mismo que

print;

* El carácter especial "\s" representa a cualquier tipo de espacio, incluyendo a "\n", así que

if (/^(\s|\n)*$/)

es lo mismo que

if (/^\s*$/)

* ¿Por qué nos has estado hablando de buscar por 'a' y 'b' si lo que buscabas era '1' y '0', y que en lugar de corchetes, ibas a usar '<' y '>'?

* Has complicado la expresión regular innecesariamente, al poner el '*' en lugar del '+', como te puse yo.

s/((0|1)\2*)/ if (length ($1) > 1) {$2 . '<' . length($1) . '>'} else {$2}/ge;

Cuando pones un '*' estás indicando que buscas por "cero o más" ocurrencias de '0' o '1'. Por eso estás luego obligado a hacer el if(), para saber si el resultado fue mayor que 1 o no. En cambio, poniendo un '+', tenemos la seguridad de que siempre habrá al menos un símbolo, así que la expresión queda

s/((0|1)\2+)/$2 . '<' . length($1) . '>'/ge;

que es la solución que te di. Con ella estamos buscando por dos o más caracteres iguales. Y la expresión regular solo modifica esas series de símbolos. Para los que solo tienen un símbolo, no son modificados porque no coinciden con el patrón. Y por eso nos ahorramos la parte del else{} que habías puesto.

Tu programa queda así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. while (<>) {
  2.     s/((0|1)\2+)/$2 . '<' . length($1) . '>'/ge;
  3.     print;
  4. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
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: Reconocer y contabilizar caracteres

Notapor koolik » 2012-04-23 17:30 @771

Hola, gracias por tu ayuda explorer.

Cuando dije contar, debí decir, tener en cuenta, ya que las líneas en blanco debo imprimirlas, no contarlas.

0 y 1, disculpas por la confusión. Es que a los efectos daba igual, debía ser un alfabeto de 2 símbolos y probando copié mal.

Necesito contabilizar si hay

* Has complicado la expresión regular innecesariamente, al poner el '*' en lugar del '+', como te puse yo.

s/((0|1)\2*)/ if (length ($1) > 1) {$2 . '<' . length($1) . '>'} else {$2}/ge;

Cuando pones un '*' estás indicando que buscas por "cero o más" ocurrencias de '0' o '1'. Por eso estás luego obligado a hacer el if(), para saber si el resultado fue mayor que 1 o no. En cambio, poniendo un '+', tenemos la seguridad de que siempre habrá al menos un símbolo, así que la expresión queda

s/((0|1)\2+)/$2 . '<' . length($1) . '>'/ge;


El problema con esa expresión es que basta que haya un 1 para que despliegue 1<n>, n cantidad de 1. Y en expresiones del tipo 0101 no se necesitan los <>.

O tal vez no te he entendido bien a ti.


pues vale, que he aprendido. ¡je!

Saludos
koolik
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2012-04-21 17:42 @779

Re: Reconocer y contabilizar caracteres

Notapor explorer » 2012-04-23 17:52 @786

koolik escribiste:El problema con esa expresión es que basta que haya un 1 para que despliegue 1<n>, n cantidad de 1. Y en expresiones del tipo 0101 no se necesitan los <>.
Supón que solo hay un '1'. Entonces el subpatrón (0|1) sí coincide. Ahora sustituimos lo que tenemos en toda la expresión ((0|1)\2+). Sería así: (11+), que quiere decir "busca un '1' seguido por uno o más '1'. Es decir: dos o más '1'. Pero originalmente sólo teníamos uno, así que no se cumple el patrón. Y por eso, cuando se encuentra con solo un '1', no lo modifica.

Prueba:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. my $_ = '0101';
  4.  
  5. s/((0|1)\2+)/$2 . '<' . length($1) . '>'/ge;
  6.  
  7. print "[$_]\n";        # sale [0101]
  8.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
La sola presencia del \2 ya garantiza que estamos localizando dos o más valores idénticos. Los demás los deja tal cual.
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

Anterior

Volver a Básico

¿Quién está conectado?

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

cron