web-dev-qa-db-de.com

Perl-Warnung: Verwendung eines nicht initialisierten Werts in Verkettung (.) Oder Zeichenfolge

Ich kann nicht herausfinden, warum die Regex-Muster nicht übereinstimmen. Die Ausgabe beklagt außerdem, dass $found nicht initialisiert wird, aber ich glaube, dass ich das getan habe. Hier ist mein Code bisher:

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

Hier ist die Ausgabe, die ich bekomme:

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:

Muss ich $found auf andere Weise initialisieren? Muss ich auch eine mehrzeilige Zeichenfolge erstellen, die als regulärer Ausdruck interpretiert wird?

Danke vielmals.

13
Dirty Penguin

Wenn die Musterübereinstimmung (=~) mit nichts übereinstimmt, wird nichts in Ihrem Skalar $found gespeichert. Daher beschwert sich Perl, dass Sie versuchen, eine Variable zu interpolieren, die keinen Wert erhalten hat. 

Sie können dies problemlos umgehen, indem Sie das Postfix verwenden, sofern folgende Bedingungen erfüllt sind:

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

Der obige Code weist $found only den Wert "Nothing" zu, sofern noch kein Wert vorhanden ist. Jetzt funktioniert Ihre Print-Anweisung in beiden Fällen immer korrekt. 

Sie können auch eine einfache if -Anweisung verwenden, die jedoch ausführlicher erscheint:

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

Eine andere Option, die möglicherweise am saubersten ist, ist das Platzieren Ihres Musters in der if-Anweisung:

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

In Ihrem regulären Ausdruck fehlt ein Trennzeichen. Fügen Sie | zwischen dem Elefanten und dem Tanzen ein.

Außerdem sollten Sie Found nur dann drucken, wenn wirklich etwas gefunden wurde. Sie können das durch beheben

print "Found: $found\n" if defined $found;
2
choroba

Doppelter Schrägstrich (//) kann auch zum Initialisieren von $found verwendet werden. Es ist unless sehr ähnlich. Sie müssen lediglich die print-Zeile wie folgt ändern.

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

Wenn $found nicht initialisiert ist, wird 'Nothing' gedruckt.

Das Ergebnis (Perl v5.10.1):

Found: Nothing
Found: Nothing
0
ahmedus