• Publicidad

Encontrar todas las palabras

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

Encontrar todas las palabras

Notapor Lalomuva » 2012-02-27 10:38 @485

Saludos. Soy nuevo en esto de programar en Perl y me acabo de unir al foro.

Escribo porque tengo duda con un script que estoy haciendo... El asunto es el siguiente: tengo un arreglo (@elementos) en el que cada elemento luce como sigue:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
  1. $elemento[0] = HPY2525: 2695|AAD08039.1 9424|ADU82245.1 F32|BAJ58597.1 hB8|CBI66079.1 Ind7|ADU79976.1 Li75|ADU83917.1 P12|ACJ08500.1 S464|ADO06203.1
  2.  
  3. $elemento[1] = HPY2525:  9424|ADU82245.1 F32|BAJ58597.1 hB8|CBI66079.1 Li75|ADU83917.1 P12|ACJ08500.1 S464|ADO06203.1
  4.  
  5. $elemento[2] = HPY2841: 9424|ADU81058.1 C20|ADO03382.1 Ind7|ADU80418.1
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Quiero meter en otro arreglo (@comunes) los elementos que contengan TODAS las palabras 2695| 9424| F32| hB8| Ind7| Li75| P12| S464| sin importar la posición de la cadena en la que aparezcan y después cuantificar los elementos del nuevo arreglo. De los elementos anteriores unicamente entraría el $elemento[0]. Entonces tengo el siguiente bloque de código:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. foreach (@elementos){
  2.         if ($_ =~ /[2695\|][9424\|][F32\|][hB8\|][Ind7\|][P12\|][S464\|][Li75\|]){
  3.                 push (@comunes, $_);
  4.                 } #fin if
  5. }#fin foreach
  6.  
  7. $size = scalar @comunes;
  8.  
  9.  
  10. print "Numero de elementos que contienen todas palabras= $size\n";
  11.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

La situación es que no sé si está bien aplicado el match, porque mi script no funciona :cry: ... Espero alguien me pueda ayudar. Gracias por su atención.
Última edición por explorer el 2012-02-27 16:12 @716, editado 3 veces en total
Razón: Marcas de texto
Lalomuva
Perlero nuevo
Perlero nuevo
 
Mensajes: 2
Registrado: 2012-02-24 18:11 @799

Publicidad

Re: Encontrar todas las palabras

Notapor explorer » 2012-02-27 11:32 @522

Bienvenido a los foros de Perl en español, Lalomuva.

El asunto no es obvio ya que, además de buscar las palabras, las debemos contar. No podemos usar una expresión regular (al menos, sencilla), porque podría darse el caso de que una palabra apareciera repetida, usurpando la aparición de otras palabras.

Entonces... podemos hacer un doble bucle para comprobar la existencia de cada palabra, en cada elemento:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. my @elemento =
  7.     (   'HPY2525: 2695|AAD08039.1 9424|ADU82245.1 F32|BAJ58597.1 hB8|CBI66079.1 Ind7|ADU79976.1 Li75|ADU83917.1 P12|ACJ08500.1 S464|ADO06203.1'
  8.     ,   'HPY2525:  9424|ADU82245.1 F32|BAJ58597.1 hB8|CBI66079.1 Li75|ADU83917.1 P12|ACJ08500.1 S464|ADO06203.1'
  9.     ,   'HPY2841: 9424|ADU81058.1 C20|ADO03382.1 Ind7|ADU80418.1'
  10. );
  11.  
  12. my @busqueda = qw(
  13.     2695| 9424| F32| hB8| Ind7| Li75| P12| S464|
  14. );
  15.  
  16. my @comunes;
  17.  
  18. for my $elemento (@elemento) {                                  # buscamos por todos los elementos
  19.  
  20.     my $numero_palabras = 0;                                    # contador de palabras encontradas, a cero
  21.    
  22.     for my $palabra (@busqueda) {                               # para todas las palabras que buscamos
  23.         $numero_palabras += $elemento =~ /\b\Q$palabra\E\b/;    # buscamos esa $palabra, en ese $elemento
  24.     }
  25.  
  26.     if ($numero_palabras == @busqueda) {                        # si el $numero_palabras encontradas is igual a las que buscamos
  27.         print "Encontrado en [$elemento]\n";
  28.         push @comunes, $elemento;                               # guardamos el elemento
  29.    }
  30. }
  31. __END__
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Hay que aclarar la expresión regular: usamos '\b' (delimitador de palabra) para asegurarnos que la palabra que buscamos no está dentro de una palabra mayor, o pegada a alguna otra. Debe ser una palabra completa, y suelta. Y el escapado '\Q...\E' nos permite usar caracteres extraños como si formaran parte de la palabra a buscar, y no formar parte de la propia expresión regular: es el caso de los caracteres '|', que son significativos para las expresiones regulares (significan alternancias de búsqueda), así que deberíamos haber puesto
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my @busqueda = qw(
  2.     2695\| 9424\| F32\| hB8\| Ind7\| Li75\| P12\| S464\|
  3. );
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
pero ese trabajo de colocar las '\' ya lo hace por nosotros '\Q...\E'.

Otra forma de escribirlo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. my @elemento =
  7.     (   'HPY2525: 2695|AAD08039.1 9424|ADU82245.1 F32|BAJ58597.1 hB8|CBI66079.1 Ind7|ADU79976.1 Li75|ADU83917.1 P12|ACJ08500.1 S464|ADO06203.1'
  8.     ,   'HPY2525:  9424|ADU82245.1 F32|BAJ58597.1 hB8|CBI66079.1 Li75|ADU83917.1 P12|ACJ08500.1 S464|ADO06203.1'
  9.     ,   'HPY2841: 9424|ADU81058.1 C20|ADO03382.1 Ind7|ADU80418.1'
  10. );
  11.  
  12. my @busqueda = qw(
  13.     2695| 9424| F32| hB8| Ind7| Li75| P12| S464|
  14. );
  15.  
  16. @busqueda = map { qr/\b\Q$_\E\b/ } @busqueda;                   # escapamos los caracteres extraños, y creamos patrones
  17.  
  18. my @comunes;
  19.  
  20. for my $elemento (@elemento) {                                  # buscamos por todos los elementos
  21.  
  22.     my $numero_palabras = grep { $elemento =~ $_ } @busqueda;   # buscamos en $elemento, por todos los patrones de @busqueda
  23.    
  24.     if ($numero_palabras == @busqueda) {                        # si el $numero_palabras encontradas is igual a las que buscamos
  25.         print "Encontrado en [$elemento]\n";
  26.         push @comunes, $elemento;                               # guardamos el elemento
  27.     }
  28. }
  29.  
  30. __END__
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Aquí, escapamos y reconvertimos las palabras a buscar en expresiones regulares, antes de aplicarlas a cada $elemento.
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: Encontrar todas las palabras

Notapor Lalomuva » 2012-02-27 16:05 @712

¡¡¡Ahh!!!... Muchas gracias. He comprendido cómo funciona... De verdad, me ayudó mucho :D
Lalomuva
Perlero nuevo
Perlero nuevo
 
Mensajes: 2
Registrado: 2012-02-24 18:11 @799


Volver a Básico

¿Quién está conectado?

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

cron