£okì has asked for the wisdom of the Perl Monks concerning the following question:

I'm having problems using =~ in my scripts basiclly I have this array called @names filled with names. I also have this varriable called $request. I need to figure out if $request is one of the names or part of one of them. currently I'm using
$j=0; $g=0; foreach $line(@vname){ chomp($line); if($vname[$j] =~ /i|"$request"/){ print qq~ <tr> <td><a href=\"mailto:$email[$j] \">$vname[$j] </a></td> </tr> ~; $g++; } $j++; }
$g just counts how many times it came up valid. my problem is it's counting names that have nothing to do with the request but not all of the names.

Edit: 2001-03-03 by neshura

Replies are listed 'Best First'.
Re: the god awful =~
by nashdj (Friar) on Dec 03, 2000 at 12:18 UTC
    /i|"$request"/ matches on either
    i or "$request" including the quotation marks

    it looks to me like you are trying to make it case insensitive, in this case your regexp should simply be /$request/i
Re: the god awful =~
by repson (Chaplain) on Dec 03, 2000 at 12:49 UTC
    I don't know if you're doing what you intended here...
    You are looping over @vname, setting $line to the current element and chomping it, then you are using the manual loop number $j to get that same element of @vname. You might want to replace the $vname[$j] with $line and remove the line $j++. Otherwise you are repeating things.
    And the regex should probably be $line=~/"$request"/i.

    Updated: Yeah for my $j (0..$#vname) was the other construct I would have recommended if I'd noticed that $email[$j] there, hmmm...don't know why I missed seeing that. Oh well.

    And the quotes might or might not be supposed to be there, probably not though, I should have guessed he didn't know regex that well when I saw the 'i' in the wrong place.

      He's not repeating things, he has another array matched with the @vname one, @email. Of course he'd be better off with either a better data structure (like a list of lists) or using this:
      for (my $j=0; $j<@vname; $j++) { #stuff here }

      Worse, he likely needs to take the double quotes out of his regex too, as others pointed out...

      --
      $you = new YOU;
      honk() if $you->love(perl)

Re: the god awful =~
by 2501 (Pilgrim) on Dec 03, 2000 at 12:11 UTC
    You are pattern matching on the letter "i". Any name with the letter "I" will trigger your program.
Re: the god awful =~
by runrig (Abbot) on Dec 03, 2000 at 23:20 UTC
    This would be a good place to use at least 'qr' (see perlop) or possibly the '/o' regex modifier (see perlre):
    my $re = qr/$request/i; my $i = my $g = 0; for my $line (@array) { chomp; if ($line =~ $re) { #do stuff print $line, $email[$i]; $g++; } } continue { $i++ }
Re: the god awful =~
by swiftone (Curate) on Dec 04, 2000 at 20:50 UTC
Re: the god awful =~
by arturo (Vicar) on Dec 04, 2000 at 03:17 UTC

    you want to find out if one of a list of names is the current string named $request depending on the length of the list of names, you *might* try building a regex out of the list of names, and testing against that.

    my @vnames = qw(bob carol ted alice); my $names_string = join "|", @vnames; # $names now => "bob|carol|ted|alice" # stuff if ($request =~ /$names/i) { # do stuff }

    That may not be very efficient if you have a long list of names, though.

    Philosophy can be made out of anything. Or less -- Jerry A. Fodor

      Maybe £okì wasnt 100% clear, but if you look at his script it is kind of the reverse. He wants to print out some text for each name that matches against $request.

      None the less, you have raised an interesting point, is repeating a regex better than a long disjunctive regex? In one script I have, I need to test around 300 words against a single sentence and strip them out (its just a psudo-ai type thing that needs to ignore a lot of psudo-useless words).

      The way its currently being done is simply:

      $foo =~ s/$_//i for (@list);

      Are there any faster/better ways than that?