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

Here is a snippet of code that will not continue to match after it hits a pattern without the @ symbol.
@addresses = $FORM{'remove'} =~/From:\s+(\w+@?[\w\.]+)/sig; for(@addresses){ print MAIL "$_\n"; }

Replies are listed 'Best First'.
Re: Expression matching
by damian1301 (Curate) on Apr 13, 2001 at 03:51 UTC
    That because you have to backslash or else the Regex engine will consider it an array, which you don't want. I also see you are not using CGI.pm judging from you %FORM usage...check out this link for reasons why you should ...


    Almost a Perl hacker.
    Dave AKA damian

    I encourage you to email me

      Make that "or else the Regex engine may consider it an array". This is actually one of the more magical parts of Perl parsing. Consider:

      #!/usr/bin/perl -w use strict; my $m= 'aeiou'; my @m= qw( a e i o u ); my $at= 'tye@perlmonks'; my $dollar= 'tye$perlmons'; sub Try { local( $" )= ","; print "(@_)\n"; } Try $at =~ /[@m]+/g; Try $at =~ /[m@]+/g; Try $dollar =~ /[$m]+/g; Try $dollar =~ /[m$]+/g; __END__ Outputs: (e,e,o) (@,m) (e,e,o) /[m5.006+/: unmatched [] in regexp at reinterp.pl line 12.

      The "rules" that control this defy simple explanation so I'll just refer you to the source code. Simply search for "weight" in the Perl source code (it is only ever mentioned in the code for this parsing which is located in the file toke.c).

              - tye (but my friends call me "Tye")
      ofcourse he could be using something like

      foreach($query->param) { $FORM{$_} = $query->param($_); }

      but that would be kinda silly :)

      Greetz
      Beatnik
      ... Quidquid perl dictum sit, altum viditur.
(tye)Re2: Expression matching
by tye (Sage) on Apr 13, 2001 at 23:57 UTC

    Using that code on the example data you provided actually works for me. So I suspect you are running into a bug in the regular expression engine in your version of Perl.

            - tye (but my friends call me "Tye")
Re: Expression matching
by Corion (Patriarch) on Apr 13, 2001 at 22:59 UTC

    Your questions in the Chatterbox and the ensuing clarification of the problem did make me go back to Mastering Regular Expressions and look up the exact meanings of the /s and /m modifier, thus you get a node here.

    In your code, you're trying to match and extract the right data in one go. This can't be done that easily, since Perl only has non-capturing lookahead and there is no lookbehind in Perl (yet). So I use a different approach, capturing the data I want into $1 and then using that to store the address into @addresses.

    Update: After amearse updated the data again, I updated my RE a bit, and now it also works with the data as posted. An extended reading of perlre or Mastering Regular Expressions might help here.

    #!/usr/bin/perl -w use strict; my $i = do { local $/; <DATA> }; my @addresses = (); while ($i =~ /^From:\s+(.*)$/mg) { push @addresses, $1; }; print join "\n", @addresses; __DATA__ From: 21755603@ad.cd.net Date: Wednesday, April 11, 2001 10:08 PM From: 21742877@rd.cd.net Date: Wednesday, April 11, 2001 07:13 PM From: Grouch Date: Sunday, February 18, 2001 08:08 AM #Anything after "Grouch" does not get matched. From: 21742877@fr.tx.net Date: Wednesday, April 11, 2001 07:13 PM
Re: Expression matching
by amearse (Sexton) on Apr 13, 2001 at 23:05 UTC
    Here is a snippet of the string I am trying to parse from my form:
    From: 21755603@ad.cd.net Date: Wednesday, April 11, 2001 10:08 PM From: 21742877@rd.cd.net Date: Wednesday, April 11, 2001 07:13 PM From: Grouch Date: Sunday, February 18, 2001 08:08 AM #Anything after "Grouch" does not get matched. From: 21742877@fr.tx.net Date: Wednesday, April 11, 2001 07:13 PM