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

Hopefully a relatively simple one for somebody, but I've been staring at it too long it's all now a blur. I have the following output generated and it's either:

Output1

====================================================================== +======== LDP Sessions ====================================================================== +======== Peer LDP Id Adj Type State Msg Sent Msg Recv Up Tim +e ---------------------------------------------------------------------- +-------- ---------------------------------------------------------------------- +-------- No Matching Entries Found ====================================================================== +========

OR

Output 2

====================================================================== +======== LDP IPv4 Sessions ====================================================================== +======== Peer LDP Id Adj Type State Msg Sent Msg Recv Up Tim +e ---------------------------------------------------------------------- +-------- 1.1.1.1:0 Targeted Established 822443 822431 273d 15:02:2 +0 ---------------------------------------------------------------------- +-------- No. of IPv4 Sessions: 1 ====================================================================== +========

I'm trying to match using the following code to trigger an IF statement. Basically I'm looking for if the output contains an IP address then stop, otherwise keep going. But, it seems my IF statement returns true even if nothing that looks like an IP address is returned. I've been on regex101 to test my matching and it checks out there, but must be something obvious!

if ( $output1 || $output2 =~ m/\d+\.\d+/gm ) { print "Found something"; exit; } else { print "Do this instead";

Replies are listed 'Best First'.
Re: Regex match multiple line output
by hippo (Archbishop) on Feb 20, 2018 at 15:45 UTC
    if ( $output1 || $output2 =~ m/\d+\.\d+/gm ) {

    That probably isn't doing what you think it is. You are testing if $output1 is true or if $output2 matches the regex. It's not entirely clear to me what you want here but this is an SSCCE which illustrates one simplistic regex matching against one of your samples but not the other. Perhaps that's what you want.

    use strict; use warnings; use Test::More tests => 2; my $wontmatch = <<EOT; ====================================================================== +======== LDP Sessions ====================================================================== +======== Peer LDP Id Adj Type State Msg Sent Msg Recv Up Tim +e ---------------------------------------------------------------------- +-------- ---------------------------------------------------------------------- +-------- No Matching Entries Found ====================================================================== +======== EOT my $willmatch = <<EOT; ====================================================================== +======== LDP IPv4 Sessions ====================================================================== +======== Peer LDP Id Adj Type State Msg Sent Msg Recv Up Tim +e ---------------------------------------------------------------------- +-------- 1.1.1.1:0 Targeted Established 822443 822431 273d 15:02:2 +0 ---------------------------------------------------------------------- +-------- No. of IPv4 Sessions: 1 ====================================================================== +======== EOT my $regex = qr/\d\.\d/; unlike ($wontmatch, $regex, 'No match'); like ($willmatch, $regex, 'Good match');
Re: Regex match multiple line output
by BillKSmith (Monsignor) on Feb 20, 2018 at 15:51 UTC

    You must check each one. Your result is always 'true' because $output1 is always 'true'.

    UPDATE: Consider using Regexp::Common::net to test for IP's.

    if ( $output1 =~ m/\d+\.\d+/m or $output2 =~ m/\d+\.\d+/m ) {

    Your use of /g is inappropriate.

    Bill

      Damn... back to the reading books... Thank you.

        bartrad: You are well advised to use Regexp::Common::net for IP matching, but be aware that by design, these regexes are not "bounded" or "delimited"; used as-is, they may match things you don't consider a proper IP and you may need to define your own regex. In the case of the  $RE{net}{IPv4} dotted-decimal IP matcher, consider:

        c:\@Work\Perl\monks>perl -wMstrict -le "use Regexp::Common qw(net); ;; my $s = '123456.4.32.123456'; ;; print qq{A: match, captured '$1'} if $s =~ m{ ($RE{net}{IPv4}) }xms; ;; my $my_ip = qr{ \b $RE{net}{IPv4} \b }xms; print qq{B: match, captured '$1'} if $s =~ m{ ($my_ip) }xms; " A: match, captured '56.4.32.123'


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

Re: Regex match multiple line output
by thanos1983 (Parson) on Feb 20, 2018 at 16:10 UTC

    Hello bartrad,

    Something like this?

    #!/usr/bin/perl use strict; use warnings; use feature 'say'; use Data::Dumper; while (<>) { chomp; if (/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/) { my @tmp = split /\s+/; # print Dumper \@tmp; say $tmp[0]; } } __END__ $ perl test.pl in.txt 1.1.1.1:0

    The input format of 'in.txt' is:

    ====================================================================== +======== LDP Sessions ====================================================================== +======== Peer LDP Id Adj Type State Msg Sent Msg Recv Up Tim +e ---------------------------------------------------------------------- +-------- ---------------------------------------------------------------------- +-------- No Matching Entries Found ====================================================================== +======== ====================================================================== +======== LDP IPv4 Sessions ====================================================================== +======== Peer LDP Id Adj Type State Msg Sent Msg Recv Up Tim +e ---------------------------------------------------------------------- +-------- 1.1.1.1:0 Targeted Established 822443 822431 273d 15:02:2 +0 ---------------------------------------------------------------------- +-------- No. of IPv4 Sessions: 1 ====================================================================== +========

    Update: Sorry I missed understood, see bellow another possible solution:

    #!/usr/bin/perl use strict; use warnings; use feature 'say'; my $output1 = "======================================================= +======================= LDP Sessions ====================================================================== +======== Peer LDP Id Adj Type State Msg Sent Msg Recv Up Tim +e ---------------------------------------------------------------------- +-------- ---------------------------------------------------------------------- +-------- No Matching Entries Found ====================================================================== +========"; my $output2 = "======================================================= +======================= LDP IPv4 Sessions ====================================================================== +======== Peer LDP Id Adj Type State Msg Sent Msg Recv Up Tim +e ---------------------------------------------------------------------- +-------- 1.1.1.1:0 Targeted Established 822443 822431 273d 15:02:2 +0 ---------------------------------------------------------------------- +-------- No. of IPv4 Sessions: 1 ====================================================================== +========"; say 'Found 1: ' . $output1 if $output1 =~ (/[0-9]+\.[0-9]+\.[0-9]+\.[0 +-9]+/); say 'Found 2: ' . $output2 if $output2 =~ (/[0-9]+\.[0-9]+\.[0-9]+\.[0 +-9]+/); __END__ $ perl test.pl Found 2: ============================================================= +================= LDP IPv4 Sessions ====================================================================== +======== Peer LDP Id Adj Type State Msg Sent Msg Recv Up Tim +e ---------------------------------------------------------------------- +-------- 1.1.1.1:0 Targeted Established 822443 822431 273d 15:02:2 +0 ---------------------------------------------------------------------- +-------- No. of IPv4 Sessions: 1 ====================================================================== +========

    Let me know if it works as expected, BR.

    Seeking for Perl wisdom...on the process of learning...not there...yet!
Re: Regex match multiple line output
by Anonymous Monk on Feb 21, 2018 at 00:34 UTC
    Remember that Perl, like most languages, uses "short-circuit" logical-expression evaluation. If the left-side of an OR condition is True, the right-side is not evaluated, because "True OR anything" is True. Similarly, if the left-side of an AND condition is False, the right-side also is not evaluated.