2013-07-08 15 views
9

Nie mogę ustalić, dlaczego wzorce regex nie pasują do siebie. Ponadto dane wyjściowe narzekają, że $found nie został zainicjowany, ale uważam, że tak. Oto mój kod do tej pory:Ostrzeżenie dotyczące Perla: użycie niezainicjowanej wartości w konkatenacji (.) Lub ciągu

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"; 
} 

tutaj jest wyjście uzyskać:

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: 

Czy muszę zainicjować $found w inny sposób? Ponadto, czy poprawnie tworzony jest wieloliniowy ciąg do interpretowania jako regex?

Wielkie dzięki.

+1

ciąg wielowierszowego jest interpretowane jako 'QR/słoń $^taniec /;' natomiast prawdopodobnie chcesz 'QR/słonia $ |^dancing /; ' – user1937198

+0

Aby dopasować wiele wierszy, użyj przełącznika/m:' my $ regex_patterns = qr/elephant $^dancing/mx; ' – shawnhcorey

Odpowiedz

14

Jeśli wzór (=~) nie pasuje do niczego, nic nie będzie przechowywane w skalarnie $found, więc Perl narzeka, że ​​próbujesz interpolować zmienną, która nie ma wartości.

Można obejść ten problem łatwo za pomocą postfix chyba warunkową:

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

Powyższy kod przypisuje wartość „nic” do $foundtylko jeśli nie ma już wartości. Teraz twoje polecenie drukowania zawsze będzie działało poprawnie, w obu przypadkach.

Można też po prostu użyć prosty if, ale to wydaje się bardziej gadatliwy:

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

Inną opcją, która może okazać się najbardziej czyste, jest postawić wzór mecz w 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

Czy mógłbyś pokazać przykład, w jaki sposób mogę dodać moje wyrażenie regularne do wiersza zawierającego" chyba że " ? –

+0

@DirtyPenguin Twoje wyrażenie regularne będzie na linii * przed * tą linią. –

+0

Dzięki za szczegółowe wyjaśnienie. :) –

2

W wyrażeniu regularnym brakuje separatora. Wstaw | między słoniem a tańcem.

Co więcej, powinieneś wydrukować Found tylko, jeśli coś naprawdę zostało znalezione. Można to naprawić przez

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

Doskonały punkt :) –

0

Double forward slash (//) może być również używany do inicjacji $found. Jest bardzo podobny do unless. Jedyną rzeczą do zrobienia jest modyfikowanie linii print w następujący sposób.

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

Jeśli $found jest niezainicjowany "Nic nie zostanie wydrukowany.

Wynik (Perl v5.10.1):

Found: Nothing 
Found: Nothing 
Powiązane problemy