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

Monks

Can someone help me with this perl pattern match, I am a newbie and write very little perl. I have a $out placeholder which could hold the following values in its

HostName: LAP3220889 TaskName: infiniteloop Next Run Time: Never Status: Last Run Time: 21:45:18, 22/06/2011 Last Result: 0 or HostName: LAP3220889 TaskName: infiniteloop Next Run Time: 11:06:00, 23/06/2011 Status: Running Last Run Time: 10:10:04, 23/06/2011 Last Result: 0 <code/> <p> I need to match taskname which is picked up from an existing variable +value, then I need to match Status: and its value (either "Running" o +r ""), then I need to match Last Result with its value. So out the d +ata I need to match the following (for example) </p> <code> TaskName: infiniteloop Status: Running Last Result: 0

This is my current code

if($out =~ m/TaskName:\s+$task.*?Status:\s+(.*?)\sLast Run Time:\s+(.* +?)\sLast Result:\s+(\d)/s) { chomp($status = $1); $result = $3;

which matches but I have to add \sLast Run Time:\s+(.*?) so it picks up Status value correctly My pattern should be

if($out =~ m/TaskName:\s+$task.*?Status:\s+(.*?)\sLast Result:\s+(\d)/ +s) { chomp($status = $1); $result = $2;

Im struggling with the match on Status, in a data dump this picks up

$VAR1 = 'infiniteloop'; $VAR2 = 'Running Last Run Time: 21:28:57, 23/06/2011'; $VAR3 = '0';

As you can see the status pattern match slurps all the data until it matches the start of "Last Result:" string from the data in $out This is probably very simple, I need a pattern to terminate at the end of status (VAR2) line and jump forward to match Last Result. Can anyone help?

Replies are listed 'Best First'.
Re: regex pattern match
by wind (Priest) on Jun 23, 2011 at 21:33 UTC
    Why not just split the data and put all of it into a hash?
    use strict; use warnings; my $data = do {local $/; <DATA>}; my %hash = map {split /:\s*/, $_, 2} map {split "\n"} $data; print "Task Name = ", $hash{TaskName}, "\n"; print "Status = ", $hash{Status}, "\n"; print "Last Result = ", $hash{"Last Result"}, "\n"; __DATA__ HostName: LAP3220889 TaskName: infiniteloop Next Run Time: Never Status: Last Run Time: 21:45:18, 22/06/2011 Last Result: 0
      Thanks for your reply, its one possibility to reference the data from an hash but the pattern match problem got me stumped, and if possible I would like to know how its done?
        pattern match problem got me stumped, and if possible I would like to know how its done? You are very close. You need to stop capturing Status at the end of the line with \n and then need to allow any number of other characters before the "Last Result:" tag. See below.

        Few other points, there is no need to mess around with $1,$2. Use list context on the left hand side and assign directly to the variables that you want. The regex matched if the rightmost of the variables is defined; in this case $result.

        use strict; use warnings; my $out = do {local $/; <DATA>}; my $task = 'infiniteloop'; my ($status, $result) = $out =~ m/TaskName:\s+$task.*?Status:\s+(.+?)\ +n.*?Last Result:\s+(\d)/s; print "status = $status\n"; # status = Running print "result = $result\n"; # result = 0 __DATA__ HostName: LAP3220889 TaskName: infiniteloop Next Run Time: 11:06:00, 23/06/2011 Status: Running Last Run Time: 10:10:04, 23/06/2011 Last Result: 0
Re: regex pattern match
by ack (Deacon) on Jun 24, 2011 at 16:12 UTC

    Here's one way. It's not very elegant but I, too, have trouble with RegEx's. I think this does what you want; but I'm sure there's a shorter or more compact way. But hopefully it's a start. Note that I put sigle quotes around the output of $value to show that white space has, indeed, been trimmed off.

    The output from this code is:

    Record No. 0 HostName = 'LAP3220889' Status = '' Last Result = '0' Record No. 1 HostName = 'LAP3220889' Status = 'Running' Last Result = '0'
    ack Albuquerque, NM