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

I am looking to use the below IF statement and have multiple conditions within it. I would then like to access each of the matched statements, but if I use the typical match variables $1 - 9, the only one filled is $1 with the last match, since it was the last successful regex match. I am looking to not have to break this in to multiple nested IF statements, each pulling a match variable and assigning it to a more permanent variable, so how do I do this, or what is the better way I should be going about this? Thank you for all replies and assistance!

if($output[$x+2] !~ /.*match1.*/ and $output[$x+2] =~ /.*(match2).*/ a +nd $output[$x] =~ /.*(match3).*/ and $output[$x+1] =~/.*(match4).*/){ #Then be able to access all matched variables }

Replies are listed 'Best First'.
Re: Perl Multiple If Conditions with Match Variables
by choroba (Cardinal) on Dec 31, 2015 at 17:58 UTC
    Hi razmeth, welcome to the Monastery!

    You can't even use the named captures, as %+ is reset on each match, too. Fortunately, you can store the matching parts in variables - just make sure the assignment forces list context:

    #!/usr/bin/perl use warnings; use strict; my @output = qw( Xmatch3X Xmatch4X Xmatch0Xmatch2X nomatch nomatch nomatchnomatch ); for my $x (0, 3) { if ($output[$x+2] !~ /.*match1.*/ and my ($m1) = $output[$x+2] =~ /.*(match2).*/ and my ($m2) = $output[$x] =~ /.*(match3).*/ and my ($m3) = $output[$x+1] =~ /.*(match4).*/ ){ print "Matched: $m1 $m2 $m3.\n"; } }

    The parentheses after my are needed for the list context.

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
      Perfect, thank you very much! I've read on here for years, but this is my first posting. I could not have asked for faster or better assistance, thank you again!
Re: Perl Multiple If Conditions with Match Variables
by Laurent_R (Canon) on Dec 31, 2015 at 18:22 UTC
    Just as an additional comment to clarify your error: $1, $2, ..., will be populated only after matches within the same regex, not in multiple successive regexes.
Re: Perl Multiple If Conditions with Match Variables
by AnomalousMonk (Archbishop) on Dec 31, 2015 at 20:33 UTC

    It's also possible to use multiple "capturing lookaheads" for a kind of logical-and effect:

    c:\@Work\Perl\monks>perl -wMstrict -le "my $s = 'xx foo yy bar zz baz'; ;; if (my ($c1, $c2, $c3) = $s =~ m{ \A (?! .* zot) (?= .* (bar)) (?= .* (baz)) (?= .* (foo)) }xms ) { print qq{c1 '$c1' c2 '$c2' c3 '$c3'}; } " c1 'bar' c2 'baz' c3 'foo'

    Update: Another trick I like is to capture match success separately for later use, e.g., in conditionals:

    c:\@Work\Perl\monks>perl -wMstrict -le "my $s = 'xx foo yy bar zz baz'; ;; my $match = my ($c1, $c2, $c3) = $s =~ m{ \A (?! .* zot) (?= .* (bar)) (?= .* (baz)) (?= .* (foo)) }xms; ;; if ($match) { print qq{c1 '$c1' c2 '$c2' c3 '$c3'}; } else { print 'no match'; } " c1 'bar' c2 'baz' c3 'foo'

    Later Update: Oops... I didn't read beyond the first two  $x+2 subscripts to realize the matches might be made against completely different variables; shoulda read choroba's reply more carefully. Oh well, the trick still works with a single variable.


    Give a man a fish:  <%-{-{-{-<