2011-10-26 8 views
16

Ogni volta che inserisco qualcosa, il codice mi dice sempre che esiste. Ma so che alcuni degli input non esistono. Che c'è?Grep per trovare l'elemento nell'array Perl

#!/usr/bin/perl 

@array = <>; 
print "Enter the word you what to match\n"; 
chomp($match = <STDIN>); 

if (grep($match, @array)) { 
    print "found it\n"; 
} 

risposta

26

Il primo arg che si dà a grep deve valutare come vero o falso per indicare se ci fosse una corrispondenza. Così dovrebbe essere:

# note that grep returns a list, so $matched needs to be in brackets to get the 
# actual value, otherwise $matched will just contain the number of matches 
if (my ($matched) = grep $_ eq $match, @array) { 
    print "found it: $matched\n"; 
} 

Se è necessario far corrispondere su un sacco di valori diversi, ma potrebbe anche essere la pena per voi di prendere in considerazione di mettere i dati array in una hash, dal momento che gli hash consentono di fare questo in modo efficace, senza dover scorrere l'elenco.

# convert array to a hash with the array elements as the hash keys and the values are simply 1 
my %hash = map {$_ => 1} @array; 

# check if the hash contains $match 
if (defined $hash{$match}) { 
    print "found it\n"; 
} 
23

Sembra che tu stia usando grep() come l'utility Unix grep, che è sbagliato.

Perl's grep() in contesto scalare valuta l'espressione per ogni elemento di una lista e restituisce il numero di volte in cui l'espressione era vera. Pertanto, quando $match contiene un valore "true", grep($match, @array) in contesto scalare restituirà sempre il numero di elementi in @array.

Invece, provare a utilizzare l'operatore pattern matching:

if (grep /$match/, @array) { 
    print "found it\n"; 
} 
+0

Penso che si potrebbe ri-parola che questo sia chiaro - anche se posso vedere quello che vuoi dire su rilettura, suona inizialmente come voi stiamo dicendo che 'grep' nel contesto scalare restituisce la lunghezza di' @ array'. Come intendi (giustamente), restituisce il numero di volte in cui l'espressione/blocco è vera. Se l'espressione è * solo una variabile * - cioè nessun confronto effettivo, solo la variabile '$ match', allora è vera per ogni elemento se la variabile stessa è vera (non vuota, diversa da zero ecc.) –

+1

@ Sam : Ho provato a riformularlo, speriamo che sia più chiaro ora. –

+1

@eugeney che mi legge molto meglio, fantastico! –

1

In aggiunta a quanto Eugenio e stevenl postato, si potrebbero incontrare problemi con l'utilizzo sia <> e <STDIN> in uno script: <> itera attraverso (= concatenando) tutti i file dati come argomenti della riga di comando.

Tuttavia, se un utente mai dimenticare di specificare un file sulla riga di comando, si leggerà da STDIN, e il codice attenderà per sempre su input

2

Ciò potrebbe essere fatto utilizzando la funzione 's List::Utilfirst:

use List::Util qw/first/; 

my @array = qw/foo bar baz/; 
print first { $_ eq 'bar' } @array; 

funzioni da List::Util come max, min, sum possono anche essere utili per voi

1

ho potuto succedere tha t se il tuo array contiene la stringa "ciao", e se stai cercando "he", grep restituisce true, anche se "he" potrebbe non essere un elemento dell'array.

Forse,

if (grep(/^$match$/, @array)) più adatto.

1

È inoltre possibile controllare singolo valore in array multipli come,

if (grep /$match/, @array, @array_one, @array_two, @array_Three) 
{ 
    print "found it\n"; 
} 
+2

Benvenuti in Stackoverflow. Ti dispiacerebbe estendere la tua risposta un po 'di più per spiegare come risolve il problema. – Daenarys