• Publicidad

Recorrido de cadenas y separación de campos

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

Notapor explorer » 2006-09-07 05:00 @250

Es por efecto de las comillas dobles. Con ellas, Perl intenta interpolar todas las variables que existan dentro de ellas, además de otras expresiones, como \r y \n. Si en cambio, usas comillas simples, la salida es tal cual la pones, así que '\r' en realidad son dos caracteres: '\' y 'r'.

Si necesitas imprimir el '$', entonces hay que indicarle que ese signo no indica que es comienzo de una variable escalar, sino que de verdad es el signo dolar. Hay que escaparlo:
Código: Seleccionar todo
print "\$INFOK*\r\n";
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

Publicidad

Notapor Josmanue » 2006-09-12 02:14 @135

Resuelto lo del acuse de recibo, gracias, ya no me acordaba de que la barra se usaba precísamente para eso, ya no se me olvida. Ahora tengo un problema más grave:
Este programa debe tratar la cadena que te mencioné y sólo esa cadena, pero el vehículo está enviando mensajes constantemente y el programa debe escuchar el puerto todo el tiempo y sólo si le llega una cadena que empieza por #xUIDxxxxx.... entonces le realizo el tratamiento, el problema es que tal y como está ahora el programa si le llega una cadena que contenga alguno de los campos por ej:
nndie jdsferiq riqVALAasf sfa f fsergSLONfadf#0UIDTR001FEC061015.....

Toma VALA y SLON como parte de la cadena, y no debe ser así. O incluso el camion se realiza chequeos y envia también la cadena '$INFOK*\r\n' que tampoco tengo por qué tratar.
¿Como puedo solucionar esto?? ¿Como hago para que no cierre la conexion al final y se quede escuchando el puerto todo el tiempo?

Por otra parte, el programa debe aprovechar la conexión establecida por los vehículos (que son los que establecen siempre la conexión) y buscar en una tabla de la BD llamada "ordenes", comprobar si para esa determinada 'UID' de vehículo hay algun mensaje (por ej. ve a tales coordenadas que hay declarado otro incendio) y si es así enviarselo.
¿Alguna idea?
Josmanue
Perlero nuevo
Perlero nuevo
 
Mensajes: 76
Registrado: 2006-06-09 04:33 @231

Notapor explorer » 2006-09-12 06:12 @300

Para lo primero, podría ser algo como un bucle infinito, y deshechando las líneas que no comiencen por '#(0|2)UID':
Código: Seleccionar todo
while ($trama = <>) {

    next unless $trama =~ /^#(0|2)UID/;

    # ....
}
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

Notapor explorer » 2006-09-12 06:25 @309

Perdón, no he leído bien el mensaje.

Parece que primero habrá que extraer la trama posible de la línea leída.

Además, decías que había que esperar por una cadena que empezase por #(0|2)UID y en el ejemplo, está en la mitad.

Yo intentaría con algo como lo siguiente: una expresión regular que detectase desde ^#(0|2) seguido de un conjunto de campos conocidos. Esta expresión regular se puede crear en base a los campos que ya tenemos. Con esa única línea puedes extraer la trama y luego el resto del programa es igual.
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

Notapor Josmanue » 2006-09-13 02:22 @140

Lo siento pero me estoy haciendo un lio con las expresiones regulares, a ver si me he enterado de algo de lo que he leido, debe ser algo parecido a lo que pusimos de:
Código: Seleccionar todo
my ($fuente) = $trama=~/^#(0|2)/;
Claro que sin guardarlo en 'fuente'.
Se supone que debo quitarle el caracter '^' para que no lo busque al principio de la linea ¿no? y detras ¿que? ¿tengo que poner la lista completa de campos? Te recuerdo que bajo algunas circunstancias podría no aparecer alguno de los campos. :x :x :x Aaaaaahh! Help!

Por otra parte para que no termine el programa he intentado meter el programa completo en un bucle
Código: Seleccionar todo
while (<>){
}
Y tambien he probado con
Código: Seleccionar todo
while ($trama = <>) {
}

Y ciertamente el programa no termina, pero tampoco me inserta nada en la base de datos, vamos de hecho no ejecuta nada, tampoco algunos print que tengo puestos por el programa a modo de comprobación. ¿Sabrias decirme por qué?
Gracias.
Josmanue
Perlero nuevo
Perlero nuevo
 
Mensajes: 76
Registrado: 2006-06-09 04:33 @231

Notapor Josmanue » 2006-09-13 05:32 @272

Una modificacion, como los bucles infinitos no me gustan nada como solucion, serán los vehiculos los que mandarán una cadena, de momento 'adios', para finalizar el programa. ¿Como puedo implementar ahora el "mientras hay_elementos y !='adios'?

¿Puede ser que mi fallo de antes fuera que no empiezo el 'while' donde debería?
Josmanue
Perlero nuevo
Perlero nuevo
 
Mensajes: 76
Registrado: 2006-06-09 04:33 @231

Notapor explorer » 2006-09-13 06:00 @291

La expresión regular sería (no lo he probado) algo como esto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my ($fuente, $trama) = $linea_leida =~ /(?:#(0|2)($campos)+)/;
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

es decir, la cabecera seguida de un conjunto de uno o más de los $campos definidos antes.

Y para salir de dentro del bucle, se puede hacer un 'last':
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
last if $linea_leida =~ /adios/;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
aunque tendrías un problema si se transmite una trama junto con un adios en la misma línea.
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

Notapor Josmanue » 2006-09-14 02:10 @132

Esto no va, ahora ya no me separa los campos y no me los va guardando en las variables. Te vuelvo a pasar el programa a ver si ves por donde falla.
Por otra parte otra modificacion, de verdad que lo siento, se que te debo estar mareando un poco, yo estoy igual pero no es culpa mia. Olvida lo que te dije de la cadena 'adios' porque no va a ir así, resulta que los camiones estan constantemente enviando un "estoy vivo" que consiste en '$nombre_camion' (por ejemplo $SP103), esto lo hacen cada minuto. La idea es aprovechar esto y salir del programa si pasan 2 o 3 minutos sin recibir nada. ¿Como puedo resolverlo? Y de verdad que muchas gracias por tu paciencia.
Última edición por Josmanue el 2006-09-25 04:30 @229, editado 1 vez en total
Josmanue
Perlero nuevo
Perlero nuevo
 
Mensajes: 76
Registrado: 2006-06-09 04:33 @231

Notapor explorer » 2006-09-17 11:34 @524

Si suponemos que un sólo programa controla a cada camión, hay que hacer un bucle infinito mientras no se cumpla la condición de parada (no hay respuesta en unos minutos, terminar el programa).

Hay varias formas de hacerlo (algo normal en Perl, claro). Pero todas ellas pasarían por la comprobación de saber si hay algo qué leer en la entrada -esto depende un poco del sistema operativo que estés usando-, y de que pase un determinado tiempo sin recibir respuesta . Con la función select() se puede realizar todo esto en una sola llamada. El cómo ya no lo sé, porque nunca lo he hecho antes. A ver si otra miembro del foro lo sabe...
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

Notapor explorer » 2006-09-17 12:52 @578

Pues ya está... es cuestión de hacer una pruebas y sale muy bien:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
    1 #!/usr/bin/perl
    2
    3 use IO::Select;
    4 use warnings;
    5 use strict;
    6
    7 my $s = IO::Select->new();
    8 $s->add(\*STDIN);
    9
   10 # Bucle de espera mientras no ocurra un timeout
   11 while ( my @canal = $s->can_read(180) ) {
   12
   13     my $trama = <>;
   14     chomp $trama;
   15
   16     # Comprobar si lo leído contiene una trama
   17     next unless $trama =~ /#(0|2).../;
   18
   19     # Procesamos la trama
   20     # ...
   21     print "\t$trama\n";
   22     # ...
   23 }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Lo que hago es meter todo el proceso en un bucle, cuya condición es esperar a que haya algo a la entrada o que pasen 180 segundos.
Si pasa ese tiempo, termina el bucle y se termina el programa.
Si no, leemos la $trama.
Si la $trama no tiene lo que buscamos, repetimos la espera.
Procesamos la $trama leída.
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

AnteriorSiguiente

Volver a Básico

¿Quién está conectado?

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