2013-07-08 21 views
9

Non riesco a capire perché i modelli di espressioni regolari non corrispondono. Inoltre, l'output si lamenta che lo $found non è inizializzato, ma credo di averlo fatto. Ecco il mio codice finora:Avviso Perl: utilizzo del valore non inizializzato in concatenazione (.) O stringa

use strict; 
use warnings; 

my @strange_list = ('hungry_elephant', 'dancing_dinosaur'); 

my $regex_patterns = qr/ 
    elephant$ 
    ^dancing 
    /x; 

foreach my $item (@strange_list) { 
    my ($found) = $item =~ m/($regex_patterns)/i; 
    print "Found: $found\n"; 
} 

Ecco l'uscita ottengo:

Use of uninitialized value $found in concatenation (.) or string at C:\scripts\perl\sandbox\regex.pl line 13. 
Found: 
Use of uninitialized value $found in concatenation (.) or string at C:\scripts\perl\sandbox\regex.pl line 13. 
Found: 

Devo inizializzare $found in altro modo? Inoltre, sto creando correttamente una stringa multi-linea da interpretare come regex?

Molte grazie.

+1

la stringa multilinea viene interpretata come 'QR/elefante $^danza /;' che, probabilmente, si vuole 'QR/elefante $ |^ballare /; ' – user1937198

+0

Per la corrispondenza multi-linea, usa l'opzione/m:' my $ regex_patterns = qr/elephant $^dancing/mx; ' – shawnhcorey

risposta

14

Se il pattern match (=~) non corrisponde a nulla, nulla sarà memorizzata nel scalare $found modo Perl si lamenta che si sta tentando di interpolare una variabile che non è stato dato un valore.

È possibile aggirare questo facilmente utilizzando il suffisso a meno condizionale:

$found = "Nothing" unless $found 
print "Found: $found\n"; 

Il codice assegna al di sopra del valore di "Niente" per $foundsolo se non ha già un valore. Ora la tua dichiarazione di stampa funzionerà sempre correttamente, in entrambi i casi.

Si potrebbe anche solo usare una semplice istruzione if, ma che sembra più prolisso:

if($found) { 
    print "Found: $found\n"; 
} 
else { 
    print "Not found\n"; 
} 

Un'altra opzione che potrebbe essere il più pulito, è quello di inserire il vostro pattern match nel if:

if(my ($found) = $item =~ m/($regex_patterns)/i) { 
    # if here, you know for sure that there was a match 
    print "Found: $found\n"; 
} 
+0

Puoi per favore mostrare un esempio di come posso aggiungere la mia regex alla tua riga contenente" unless " ? –

+0

@DirtyPenguin La tua espressione regolare sarà sulla linea * prima * di quella linea. –

+0

Grazie per la spiegazione dettagliata. :) –

2

Nell'espressione regolare manca un separatore. Inserisci | tra l'elefante e la danza.

Inoltre, è necessario stampare Found solo se è stato effettivamente trovato qualcosa. È possibile risolvere che

print "Found: $found\n" if defined $found; 
+0

Punto eccellente :) –

0

Double forward slash (//) può anche essere utilizzata per inizializzare $found. È molto simile a unless. L'unica cosa da fare è modificare la riga print come segue.

print "Found: " . ($found // 'Nothing') . "\n"; 

Se $found è inizializzato, verrà stampata 'Nothing'.

L'esito (Perl v5.10.1):

Found: Nothing 
Found: Nothing 
Problemi correlati