• Publicidad

regexp con excepciones

Así que programas sin strict y las expresiones regulares son otro modo de hablar. Aquí encontrarás respuestas de nivel avanzado, no recomendable para los débiles de corazón.

regexp con excepciones

Notapor jrblas » 2012-03-25 11:02 @501

La expresión regular: "[A-Z]{3}[^F]{3}" reconocerá:

AQUSOL BARNEY FREDER ...

pero no...

AQUSOF BARNFY FREFER 1REDER ...

Cómo puedo decirle que, en vez de exigir 3 repeticiones de [A-Z] y 3 repeticiones de [^F], exija 2 repeticiones de [A-Z] en las tres primeras posiciones, independientemente de la posición en la que se den, y lo mismo para las repeticiones de [^F], de forma que sean válidas:

AQUSOF 1QUSOF A1USOF AQ1SOF AQ1FOL ...

En resumen, que cuando le pido "3 repeticiones de..." entienda "3 repeticiones de... pero puedes equivocarte una vez". ¿Hay forma de meter eso en la expresión regular?

Gracias,
JR
jrblas
Perlero nuevo
Perlero nuevo
 
Mensajes: 1
Registrado: 2012-03-25 10:52 @494

Publicidad

Re: regexp con excepciones

Notapor explorer » 2012-03-25 14:23 @641

Bienvenido a los foros de Perl en Español, jrblas.

No sé si entiendo lo que quieres hacer, pero entre la reglas de las expresiones regulares no existe el concepto de 'excepción' a la regla. Bueno, sí, pero esa excepción debe formar parte, a su vez, de una regla.

Por lo que veo, quieres que identifique palabras compuestas de tres primeras letras cualesquiera, seguida de otras tres letras en las que, necesariamente, debe haber una 'F'.

Eso se puede hacer con lo siguiente:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. my @palabras = qw(
  3.     AQUSOF 1QUSOF A1USOF AQ1SOF AQ1FOL
  4.     AQUSOL BARNEY FREDER
  5.     AQUSOF BARNFY FREFER 1REDER
  6.   );
  7.  
  8. for my $palabra (@palabras) {
  9.  
  10.   print "[$palabra] : ";
  11.  
  12.   my $encontrada =
  13.     $palabra =~ m/^.{3}(.{3})$/;
  14.  
  15.   my $segunda_parte = $1;
  16.  
  17.   if ($encontrada  and  $segunda_parte =~ /F/) {
  18.     print "si\n";
  19.   }
  20.   else {
  21.     print "no\n";
  22.   }
  23. }
  24.  
  25. __END__
  26. [AQUSOF] : si
  27. [1QUSOF] : si
  28. [A1USOF] : si
  29. [AQ1SOF] : si
  30. [AQ1FOL] : si
  31. [AQUSOL] : no
  32. [BARNEY] : no
  33. [FREDER] : no
  34. [AQUSOF] : si
  35. [BARNFY] : si
  36. [FREFER] : si
  37. [1REDER] : no
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

Esta es otra versión un poco más compacta. Usamos una aserción consiguiente para que compruebe que lo que sigue al primer bloque de tres letras, son otras tres, y nada más. Y luego comprobamos que en esas tres letras al menos exista una 'F':
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. my @palabras = qw(
  4.     AQUSOF 1QUSOF A1USOF AQ1SOF AQ1FOL
  5.     AQUSOL BARNEY FREDER
  6.     AQUSOF BARNFY FREFER 1REDER
  7.     XXXXFXX
  8.   );
  9.  
  10. for my $palabra (@palabras) {
  11.  
  12.   print "[$palabra] : ";
  13.  
  14.   my $encontrada = $palabra =~ m/^.{3}(?=.{3}$).*F{1,3}.*$/;
  15.  
  16.   if ($encontrada) {
  17.     print "si\n";
  18.   }
  19.   else {
  20.     print "no\n";
  21.   }
  22. }
  23.  
  24. __END__
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
(La palabra XXXXFXX está para verificar que, efectivamente, descarta aquellas palabras de más de 6 letras, aunque tengan una 'F'.)

No sé si es esto lo que buscas...

Más información en perldoc perlre (traducido).
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


Volver a Avanzado

¿Quién está conectado?

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

cron