Chris Doyle
Chris Doyle

Reputation: 12145

Line being matched by regex which shouldnt match

I am tyring to use flip flop to parse through a log file and print datetime and result of some responses. the time and the result are on different lines. What i cant understand is why I am getting a match on a line which shouldnt match.

SOURCE FILE

2014-10-30 15:31:42,043 DEBUG Result
<retData xmlns="">
<retCode>rcSuccess</retCode>
2014-10-30 15:31:42,747 DEBUG Result
<retData xmlns="">
<retCode>rcSuccess</retCode>

This is the perl one liner i am using trying to debug but the retData line is matched and i dont know why

cat chris_sample.log1 | perl -ne 'chomp; if (/^(.*)\sDEBUG.*Result/ .. /<retCode>(\w+)<\/retCode>/){print "SOURCE: $_ \nCAPTURED: $1 \nMATCHED: $&\n" } else { print "NOTSOURCE: $_\n"}'

OUTPUT

SOURCE: 2014-10-30 15:31:42,043 DEBUG Result
CAPTURED: 2014-10-30 15:31:42,043
MATCHED: 2014-10-30 15:31:42,043 DEBUG Result
SOURCE:   <retData xmlns="">
CAPTURED: 2014-10-30 15:31:42,043
MATCHED: 2014-10-30 15:31:42,043 DEBUG Result
SOURCE:     <retCode>rcSuccess</retCode>
CAPTURED: rcSuccess
MATCHED: <retCode>rcSuccess</retCode>
SOURCE: 2014-10-30 15:31:42,747 DEBUG Result
CAPTURED: 2014-10-30 15:31:42,747
MATCHED: 2014-10-30 15:31:42,747 DEBUG Result
SOURCE:   <retData xmlns="">
CAPTURED: 2014-10-30 15:31:42,747
MATCHED: 2014-10-30 15:31:42,747 DEBUG Result
SOURCE:     <retCode>rcSuccess</retCode>
CAPTURED: rcSuccess
MATCHED: <retCode>rcSuccess</retCode>

why is retData showing as a match and its match shows as the one from the line before?

Upvotes: 0

Views: 43

Answers (1)

Sobrique
Sobrique

Reputation: 53498

Oneliners are bad for debugging, as a rule.

However - you're using a range operator:

 if (/^(.*)\sDEBUG.*Result/ .. /<retCode>(\w+)<\/retCode>/)

This is true if you're between these two markers. The retData line is between these two markers, and is therefore printed when you do:

print "SOURCE: $_";

It's not actually being matched, so $1 and $& are being used from the previous pattern match.

Following on from comments - best I can do for extracting the bits you want:

{
    local $/;
    print join ( "\n", ( <DATA> =~ m/^([\d\-\,\:\s]+)?\s+DEBUG\sResult
                         .*?
                         <retCode>(\w+)<\/retCode>
                                                  /xmsg )) ;
}


__DATA__ 
2014-10-30 15:31:42,043 DEBUG Result
<retData xmlns="">
<retCode>rcSuccess1</retCode>
2014-10-30 15:31:42,747 DEBUG Result
<retData xmlns="">
<retCode>rcSuccess2</retCode>

Downside is - it's doing multi-line matching on the whole input, rather than working line by line.

Upvotes: 2

Related Questions