• Publicidad

Evaluar cadena de solo números

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

Evaluar cadena de solo números

Notapor primitivo » 2013-07-27 10:22 @474

Hola, un saludo.

El día de hoy quise condicionar una variable de modo que solo pueda obtener números.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. my $num = <STDIN>;
  4.  
  5.  
  6. if ($num == /[\d+]/)
  7. {
  8.          print "OK";
  9.          $num = <STDIN>;
  10. } else {
  11.        print "FAIL";
  12.        $num = <STDIN>;
  13. }
  14.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Estuve intentando, pero no lo he logrado, ¿Me colaboran?
primitivo
Perlero nuevo
Perlero nuevo
 
Mensajes: 80
Registrado: 2013-03-22 23:05 @004

Publicidad

Re: Evaluar cadena de solo números

Notapor explorer » 2013-07-27 10:39 @485

Hay varias formas de hacerlo, pero antes, fíjate que has puesto el operador de comparación de igualdad de números, cuando en realidad querías utilizar el operador de expresiones regulares.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. my $numero = <STDIN>;
  3. chomp $numero;                               # Quitamos el carácter de nueva línea
  4.  
  5. if ($numero =~ /^\d+$/) {                    # ¿$numero coincide con un conjunto de dígitos?
  6.     print "Sí, es un número: [$numero]\n";
  7. }
  8. else {
  9.     print "No es un número\n";
  10. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Otra forma sería convertir el contenido en número. Eso hace que Perl descargue todos los caracteres que no forman parte de la notación de un número.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. my $numero = <STDIN>;
  3. $numero = 0+ $numero;                        # Conversión a número: le sumamos un cero
  4.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Lo malo es que si el usuario mete algo raro, siempre acabaremos con $numero valiendo 0.

Perl admite varias notaciones para expresar números (extraído de perlnumber):
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
           $n = 1234;              # decimal integer
           $n = 0b1110011;         # binary integer
           $n = 01234;             # octal integer
           $n = 0x1234;            # hexadecimal integer
           $n = 12.34e-56;         # exponential notation
           $n = "-12.34e56";       # number specified as a string
           $n = "1234";            # number specified as a string
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

También, con Regexp::Common, además de comprobar si lo que tenemos es un número, nos devuelve las distintas partes que lo componen (exponente, parte entera, parte decimal, signo, etc.).

Otros módulos:
  • Test::Numeric, comprobaciones al estilo Test
  • autobox::Core trae un método llamado is_number(), que devuelve verdadero si la variable que lo usa contiene un número válido para Perl
  • Data::Util, módulo genérico de comprobación de datos
  • ...
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: Evaluar cadena de solo números

Notapor primitivo » 2013-07-27 10:42 @487

Lo tengo así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  
  2. #!/usr/bin/perl
  3.  
  4.  
  5. my $num = <STDIN>;
  6.  
  7.  
  8. if (($num =~ /[0-9]+/) and ($num !~ /[a-zA-Z]/))
  9. {
  10.          print "OK\n";
  11.          print "PID $$\n";
  12.          print "UID $<\n";
  13.          $num = <STDIN>;
  14. } else {
  15.        print "FAIL\n";
  16.        print "PID $$\n";
  17.        print "UID $<\n";
  18.        $num = <STDIN>;
  19. }
  20.  
  21.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¿Es fiable?
primitivo
Perlero nuevo
Perlero nuevo
 
Mensajes: 80
Registrado: 2013-03-22 23:05 @004

Re: Evaluar cadena de solo números

Notapor explorer » 2013-07-27 11:02 @501

No, no lo es. Te vale con probarlo para darte cuento de que algo no funciona.

Debes recordar que cuando lees algo por el teclado, ese "algo" incluye el/los caracteres de nueva línea. Si no los vas a usar, es mejor que los quites con chomp().

En el if() tienes puesto esto: if (($num =~ /[0-9]+/) and ($num !~ /[a-zA-Z]/)), que quiere decir:
  • la condición entera es verdadera si las dos siguientes lo son
  • la primera condición es verdadera si $num contiene, en alguna parte dentro de ella, un conjunto de uno o más dígitos
  • la segunda condición es verdadera si $num no contiene ningún carácter alfabético normal
La primera parte de la condición puede fallar si el usuario introduce esto: "Juan 23". La expresión regular devolverá verdadero, pero vemos claramente que no es un número.

Y la segunda parte devolverá verdadero aun cuando el usuario introduzca algo que no sea un número: recuerda que si no quitas el carácter de nueva línea, sigue estando dentro de la variable, y como esos caracteres son distintos de los alfabéticos, la expresión regular devolverá verdadero. Así que incluso devolverá verdadero con esta cadena: "Hola", ya que contiene, al final, el carácter de nueva línea.

No sé por qué luego vuelves a leer otra entrada desde el STDIN, a la misma variable.
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: Evaluar cadena de solo números

Notapor primitivo » 2013-07-27 11:08 @505

Es que uso ActivePerl, y con STDIN evito que se cierre cuando se ejecuta, y veo si funciona o no /xD/

En realidad no emplearé la condición por teclado, enviaré la variable por socket.
primitivo
Perlero nuevo
Perlero nuevo
 
Mensajes: 80
Registrado: 2013-03-22 23:05 @004

Re: Evaluar cadena de solo números

Notapor explorer » 2013-07-27 11:20 @514

Estás trabajando mal con Perl.

Debes hacer esto: en una aplicación editas Perl (puede ser un editor o un IDE). Al mismo tiempo, tienes abierto el CMD.exe (la aplicación de línea de comandos de Windows). En esta aplicación, te has colocado en el directorio donde estás editando el programa Perl.

Entonces, con Alt+tabulador pasas de una aplicación a otra. Cuando terminas de editar el programa, lo guardas (con la combinación del teclado que sea), pulsas Alt+Tab para pasar a la línea de comandos, y escribes perl programa.pl (esto solo la primera vez, las siguientes, bastará con pulsar Flecha Arriba) y luego pulsas Intro.

Perl ejecutará el programa y verás la salida en pantalla. Otro Alt+Tab y ya vuelves al editor. Y repetir.

Otra forma de trabajo: algunos IDE, como Eclipse, permiten ejecutar desde ellos mismos, y ver la salida en un panel propio.

Creo recordar que Komodo EDIT, de ActiveState, también tiene algo así.
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: Evaluar cadena de solo números

Notapor primitivo » 2013-07-27 11:24 @517

Vale, asi lo haré (aún sigo siendo novato)

pero ahora quiero validar una fecha de nacimiento en formato DÍA/MES/AÑO

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3.  
  4. my $set_val = <STDIN>;
  5.  
  6. $set_val =~ s///;
  7.  
  8. if (($set_val =~ /\/{3}/) and ($set_val =~ /[0-9]+/) and ($set_val !~ /[a-zA-Z]/))
  9. {
  10.           my @num2 = split("/",$set_val);
  11.           print "$num2[0] $num2[1] $num2[2]\n";
  12.           print "OK\n";
  13.           print "PID $$\n";
  14.           print "UID $<\n";
  15.           $set_val = <STDIN>;
  16.          
  17. } else {
  18.        print "FAIL\n";
  19.        print "PID $$\n";
  20.        print "UID $<\n";
  21.        $set_val = <STDIN>;
  22. }
  23.  
  24.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Pero no me da lo que espero
primitivo
Perlero nuevo
Perlero nuevo
 
Mensajes: 80
Registrado: 2013-03-22 23:05 @004

Re: Evaluar cadena de solo números

Notapor explorer » 2013-07-27 11:32 @522

No nos dices qué formato de fecha esperas... y hay muchos...

Por ejemplo, 27/7 es correcta, porque representa el día de hoy. No hace falta indicar el año porque se toma el actual (así es como funciona en las hojas de cálculo, por ejemplo). Y la cifra del mes, no está rellena de ceros a la izquierda.

07/07/11 también es correcta, en este caso con relleno de ceros, salvo en el año.

En fin... muchos...
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: Evaluar cadena de solo números

Notapor primitivo » 2013-07-27 11:47 @533

Espero un formato

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #10/5/1990
  2. #lo cual sería la de nacimiento.
  3.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


PD: Gracias por tu tiempo explorer
primitivo
Perlero nuevo
Perlero nuevo
 
Mensajes: 80
Registrado: 2013-03-22 23:05 @004

Re: Evaluar cadena de solo números

Notapor explorer » 2013-07-27 11:57 @539

Sigues sin decirnos el formato (relleno con ceros o no, en la parte de días y meses), pero supondremos que los números no se rellenan con ceros, viendo el ejemplo.

Entonces, se podría hacer algo así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!Perl
  2. my $fecha = <>;
  3. chomp $fecha;
  4.  
  5. if ( $fecha =~ m{^\d{1,2}/\d{1,2}/\d{4}$} ) {
  6.     print "Sí es una fecha real\n";
  7. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
La expresión regular quiere decir:
  • De principio (^) a fin ($), debe coincidir con,
  • uno o dos dígitos, seguidos de un carácter '/', seguidos por
  • uno o dos dígitos, seguidos de un carácter '/', seguidos por
  • cuatro dígitos
El problema es que... tampoco podemos estar seguros de que sea una fecha real... El usuario podría entrar esto: 9/99/9990, o esta otra: 27/17/1967, así que quedaría un paso más que sería comprobar si es una fecha real.

Quedaría una comprobación más: si es una fecha de nacimiento, la fecha debe ser anterior a la actual, salvo que sea un viajero del tiempo :)
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

Siguiente

Volver a Básico

¿Quién está conectado?

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

cron