• Publicidad

Problema con regexp

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

Problema con regexp

Notapor newperlero » 2011-10-10 05:29 @270

Tengo un fichero así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
-Oct  3 10:32:49 2011 VC:8:1 Slot 4: 1317630761:  Used by PRODUCCION\Exchangeadmin on MSTDCBOSNA
-Oct  3 10:32:49 2011 VC:8:1 Slot 8: 1317630762:  Infected file modified by AntiVirus Engine
-Oct  3 10:32:49 2011 VC:8:1 Slot 9: 1317630762:  \root\fs_fb003\R\j2re1.4.2_08\bin\jucheck.exe
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Y por otra parte tengo un array de usuarios, que contiene los usuarios que quiero chequear, por ejemplo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $usuarios[0]='PRODUCCION\Exchangeadmin';
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

Necesito comprobar que la línea contenga al usuario, y si lo tiene o no, hacer unas tareas u otras. Estoy haciendo
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. if($linea =~ m/$usuario/){}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
pero no entra al bucle. ¿Tengo que hacer algo especial para comprobar si una línea contiene el valor de una variable?
newperlero
Perlero nuevo
Perlero nuevo
 
Mensajes: 42
Registrado: 2011-07-15 06:38 @318

Publicidad

Re: Problema con regexp

Notapor explorer » 2011-10-10 05:59 @291

El problema está en el propio nombre del $usuario: contiene un '\', y ese es un carácter que es significativo para las expresiones regulares.

Tenemos que "escapar" su significado, para que la expresión regular busque por un '\' literal, y no otra cosa.

Una solución es usar "\Q ... \E" para que Perl "escape" esos caracteres extraños:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. my @usuarios = qw<
  4.     PRODUCCION\Exchangeadmin
  5. >;
  6.  
  7. while (my $linea = <DATA>) {
  8.     for my $usuario (@usuarios) {
  9.         if ($linea =~ m/\Q$usuario\E/) {
  10.             print "Encontrado: $linea";
  11.         }  
  12.     }  
  13. }
  14.  
  15.  
  16. __DATA__
  17. -Oct  3 10:32:49 2011 VC:8:1 Slot 4: 1317630761:  Used by PRODUCCION\Exchangeadmin on MSTDCBOSNA
  18. -Oct  3 10:32:49 2011 VC:8:1 Slot 8: 1317630762:  Infected file modified by AntiVirus Engine
  19. -Oct  3 10:32:49 2011 VC:8:1 Slot 9: 1317630762:  \root\fs_fb003\R\j2re1.4.2_08\bin\jucheck.exe
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

De todas maneras, como estamos buscando si una cadena está dentro de otra, es mucho más eficiente usar la función apropiada para eso: index() (o rindex(), según el caso). Nos devolverá un valor, que es la posición donde se encuentra lo que estamos buscando.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.         if (index($linea, $usuario) != -1) {
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Otra opción es la de meter a todos los usuarios ("escapados") en una gran "alternancia", de tal manera que la expresión regular solo se compila una vez:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. my @usuarios = qw<
  4.     PRODUCCION\Exchangeadmin
  5.     jucheck
  6. >;
  7.  
  8. my $usuarios = join q[|], map { quotemeta } @usuarios;
  9.  
  10. $usuarios = qr/$usuarios/o;
  11.  
  12. while (my $linea = <DATA>) {
  13.  
  14.     if ($linea =~ $usuarios) {
  15.             print "Encontrado: $linea";
  16.     }
  17. }
  18.  
  19. __DATA__                  
  20. -Oct  3 10:32:49 2011 VC:8:1 Slot 4: 1317630761:  Used by PRODUCCION\Exchangeadmin on MSTDCBOSNA
  21. -Oct  3 10:32:49 2011 VC:8:1 Slot 8: 1317630762:  Infected file modified by AntiVirus Engine
  22. -Oct  3 10:32:49 2011 VC:8:1 Slot 9: 1317630762:  \root\fs_fb003\R\j2re1.4.2_08\bin\jucheck.exe
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

quotemeta() hace lo mismo que "\Q...\E". Metemos a todos los usuarios en un patrón, separados con alternancias "|", y creamos una variable que almacena una expresión regular, con qr().

Así, nos ahorramos el bucle de @usuarios, y la expresión regular solo se ejecuta una vez por $linea.
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: Problema con regexp

Notapor newperlero » 2011-10-10 06:08 @297

Eres una máquina, ya lo tengo apañado, ¡¡gracias!!
newperlero
Perlero nuevo
Perlero nuevo
 
Mensajes: 42
Registrado: 2011-07-15 06:38 @318


Volver a Básico

¿Quién está conectado?

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

cron