由不匹配的正则表达式匹配的行

时间:2014-10-30 16:40:58

标签: regex perl

我正在使用触发器来解析日志文件并打印日期时间和一些响应的结果。时间和结果是不同的。我无法理解的是为什么我在一条不匹配的线上获得一场比赛。

消息来源

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>

这是我正在尝试调试的perl one liner,但retData行匹配,我不知道为什么

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

输出

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>

为什么retData显示为匹配且其匹配显示为之前的行?

1 个答案:

答案 0 :(得分:2)

Oneliners通常不适合调试。

然而 - 您正在使用范围运算符:

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

如果你在这两个标记之间,那就是这样。 retData行位于这两个标记之间,因此在执行此操作时会打印:

print "SOURCE: $_";

实际上并没有匹配,因此在前一个模式匹配中使用了$1$&

继续发表评论 - 我最好能够提取你想要的位:

{
    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>

下行是 - 它在整个输入上进行多线匹配,而不是逐行工作。