2010-10-27 2 views
2

J'ai un hachage, où les clés et les valeurs proviennent de correspondances dans une expression régulière. J'ai du mal à extraire les valeurs en fonction des clés. Dans l'intérêt de la brièveté et du rodage du problème, ma première version de ce post a tenté de réduire mon programme aux seules parties pertinentes, mais ce n'était pas suffisant, alors c'est plus. Les noms de variable et de fichier ont été modifiés, mais la syntaxe est vraie. Bien que les expressions régulières spécifiques ne soient pas pertinentes, je les ai incluses sur demande.Pourquoi ma variable Perl n'a-t-elle pas la bonne valeur en dehors du bloc if()?

use strict; 
my %Hash =(); 
my $logName = "MyLogName.Log"; 
open (LOG, '<', $logName) or die ("Couldn't open log ".$logName); 

while (my $line = <LOG>) { 
    chomp $line; 
    if ($line =~ m/.*-t\s+(.+?),\s+(.+?)$/ix) { 
    # This print statement shows that I have correctly extracted what I want. 
    print ("Key::".$1."::Value::".$2."\n"); 
    my $key = $1; 
    chomp $key; 
    my $value = $2; 
    chomp $value; 
    $Hash{$key} = $value; 

    } 
} 
close LOG; 

#This shows the hash has been filled correctly. It shows all the keys and values 
# I expect to see. 
while ((my $newkey, my @newvalue) = each %Tests) { 
    print "Key##".$newkey."##NewValue:".$Tests{$newkey}."\n"; 
} 

open (FILE, '<', "file.csv') or die ("Couldn't open csv file"); 

while (my $newLine = <FILE>) { 
    chomp $newLine; 
    if ($newLine =~ m/^(.+?),\s+(.+?)\s*?(.+?)$/ix) { 
    #This print statment verifies I've captured them correctly 
    print $1."::".$2."::".$3."\n"; 
    my $val1 = $1; 
    my $val2 = $2; #This is the same as the key in %Hash 
    my $val3 = $3; 
    #For good measure... 
    print $val1."::".$val2."::".$val3."\n"; 

    my $oldVal = $Hash{$val2}; 
    print "oldVal::".$Hash{$val2}." "; #This line prints only the space 
    print "\$oldVal::".$oldVal."\n"; #This line prints only the newline 

    # Intent: put oldVal, val1, and val3 in an array and replace the old value 
    # in %Hash with the array, so I'd have a hash of arrays. 
    } 
} 
close FILE; 

J'utilise Perl v5.10.1 dans Cygwin. Les instructions d'impression vérifient que la clé lue dans le premier fichier est identique à celle lue dans le deuxième fichier; les regex ont ramassé exactement ce que je les veux. Le hachage est global. Pourquoi ces instructions d'impression ne finissent-elles pas par extraire la valeur du hachage, étant donné la clé correcte?

+3

Exécuter ce dans le débogueur et utilisez la commande « x » pour vider la valeur du hachage et les clés pour confirmer que: a) le hachage contient les clés que vous attendez, et b) les clés sont vraiment identiques. –

+5

Se pourrait-il que votre 'valeur $ 'soit hors champ à la fin du deuxième bloc? Vous vérifiez sa valeur avant qu'elle ne soit hors de portée, n'est-ce pas? – CanSpice

+3

Je n'ai aucune idée de ce que vous faites. Pourquoi capturez-vous des chaînes vides? –

Répondre

2

Passez par le processus de débogage normal. Assurez-vous que les valeurs sont ce que vous pensez qu'elles sont.

Vérifiez que le hachage a les clés et les valeurs que vous pensez qu'il a:

use Data::Dumper; 

print Dumper(\%Hash); 

Dans votre code, vérifier les valeurs à chaque étape:

if ($line2 =~ m/ () () () /ix { 
    my $key = $1; 
    chomp $key; 
    print "key is [$key]\n"; 
    my $value = $Hash{$key}; 
    print "value is [$value]\n"; 
    } 

Je parie que vous découvrirez cette valeur de $ est très bien définie, donc votre problème est quelque chose d'autre, comme le fait que $value est portée lexicalement et que vous ne faites rien avec elle donc il disparaît à la fin du bloc. Vous voulez sans doute attribuer cette valeur au-dessus de ce bloc:

my $value = do { 
    if ($line2 =~ m/ () () () /ix { 
     my $key = $1; 
     chomp $key; 
     print "key is [$key]\n"; 
     $Hash{$key}; 
     } 
    }; 

print "value is [$value]\n"; 
2

Vous pouvez certainement utiliser des variables de correspondance d'expressions régulières comme clés de hachage. Il n'y a pas de différence entre ceux-ci et toute autre chaîne. Si vous voulez une réponse plus complète, je suggère d'afficher vos expressions régulières réelles avec quelques exemples de lignes d'entrée qui causent le problème.

-2
use strict; 
use warnings; 
Questions connexes