http://qs321.pair.com?node_id=436409

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

My question to you perl experts is this: would it be possible to assign a particular result if it doesnt find a match? Would it be better to use something else besides the matching operator? Is there an operator to state if nothing matches? I have a list of users stored in an array called @names(20 names) in this format "MANDERSON/Anderson MikeD|MikeD.Anderson\\". @cdwv_list has a list of 10 names stored with this format "MANDERSON". Here is an example of the code:
for ($j = 0; $j < @cdwv_list; $j++) { $user_id = $cdwv_list[$j]; foreach $names(@names) { if ($names =~ $user_id) { #if match I want it to grab name $names =~ /\/([\w\s]+)\|/; $name = $1; } #So what do I put here or somewhere else if #the 1st $name doesnt match any of the 10 #users from @cdwv_list? I tried: else { #But it only prints this 10 times #even thought only 1 name doesnt #match between the two list print "Name does not exist\n"; } } }
Thanks in advance.... Thomas

Replies are listed 'Best First'.
Re: To Pattern Match or not to Pattern Match
by Roy Johnson (Monsignor) on Mar 04, 2005 at 00:05 UTC
    Try #2: I just realized what you're expecting it to do. You have nested loops, and your test is inside the innermost loop. So it's going to run 20 times (inner loop) for each of the 10 names (outer loop).

    The "operator to state if nothing matches" might be grep. Something like:

    for my $user_id (@cdwv_list) { my ($names) = grep(/^\Q$user_id/, @names); if ($names) { ($name) = $names =~ /\/([\w\s]+)\|/; } else { print "$userid does not exist in name list\n"; } }

    Caution: Contents may have been coded under pressure.
      Roy Johnson, thanks for your help. The code works exactly like what I needed. Thanks to everyone else that responded. If I had any sort of pts or anything to give you guys I would. I greatly appreciate the help. --Thomas
Re: To Pattern Match or not to Pattern Match
by Zed_Lopez (Chaplain) on Mar 04, 2005 at 00:15 UTC

    I'd make a hash out of @cdvw_list, and parse the id out of every name, and base my test on whether the id exists in the list:

    my %cdwv_hash; @cdwv_hash{@cdwv_list} = (1) x @cdwv_list; for (@names) { my ($id, $name) = (m{^([^/]+)/([^|]+)|}); if (exists $cdwv_hash{$id}) { print "$id: $name\n"; } else { print "No match for $_ in cdwv_list\n" } }
Re: To Pattern Match or not to Pattern Match
by sh1tn (Priest) on Mar 04, 2005 at 00:17 UTC
    Array elements existence check:
    my @all = 1..10; my @some = 1..5; my %h; my @c; @h{@some} = ( ); # Elements that exist in both arrays exists($h{$_}) and push @c, $_ for @all; # @c: 1 2 3 4 5 # Elements that do not exist in @some array exists($h{$_}) or push @c, $_ for @all; # @c: 6 7 8 9 10
    Pattern matching negation:
    my $string = 'string'; # true: $string =~ /^string$/ and print "$string is really string?\n"; # false: $string !~ /^string$/ and print "$string is not string?\n"; # STDOUT: string is really string


Re: To Pattern Match or not to Pattern Match
by Roy Johnson (Monsignor) on Mar 03, 2005 at 23:57 UTC
    Your first attempt at matching doesn't include the surrounding //s for your pattern. Not sure if that's what's troubling you.

    Incidentally, the more perlesque way to write your for loop is

    for my $user_id (@cdwv_list) {

    Caution: Contents may have been coded under pressure.
Re: To Pattern Match or not to Pattern Match
by mlh2003 (Scribe) on Mar 03, 2005 at 23:56 UTC
    In your else block, you need to add 'last;' to exit the inner loop and go to the next element in the outer loop.
    else { print "Name does not exist\n"; last; }
    That should prevent that line from printing 10 times.
    --------------------
    mlh2003
      I think the problem here is that it loops through the 1st 10 names in @names and since none of those 10 matches it prints out "Name does not exist" 10 times. I need it to loop through all 20 strings in @names and if it doesnt find a match then print "Name does not exist" only once, buts only my guess.