perl多行问题:需要一根衬纸在文件中的字符串之前打印最后一个匹配项

时间:2018-07-10 17:14:57

标签: regex perl multiline

我有一个这样的日志文件:

2018-07-10 10:03:01: random text1
2018-07-10 10:03:02: random text2
2018-07-10 10:03:03: random text3
    more text
    and more
    THIS IS MATCHED STRING
2018-07-10 10:03:04: random text4

我想使用perl一线式查找“此匹配的字符串”之前的最新时间戳。

我尝试过:

perl -0777 -nle 'print "$1\n" while m/(\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d).+?THIS IS MATCHED STRING/sg'

但它与第一​​个时间戳“ 2018-07-10 10:03:01”匹配,而不是我想要的“ 2018-07-10 10:03:03”。显然(至少我认为),我对贪婪/惰性匹配的工作方式没有很好的了解。

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:3)

对于一个相当基本的方法,它避免涉及正则表达式,逐行处理,并且在匹配时间戳模式时将其记录下来。然后,当您遇到模式THIS...时,您将拥有(最后一个)上一个时间戳。

perl -wnE'
    $ts = $1 if /(\d{4}-\d{2}-\d{2}[ ]\d{2}:\d{2}:\d{2})/; 
    say $ts // "no previous time stamp"  if /THIS IS MATCHED STRING/;
' file.txt

如果使用($ts) = /.../捕获并保存了时间戳,则失败的匹配行没有将其打开undef,因此找到THIS时可能不存在。因此,只有在存在匹配项时,它才会从$1中保存。

如果文件在//之前完全没有时间戳记,则使用$ts上的定义或(THIS

答案 1 :(得分:0)

您可以使用

^
(\d{4}-\d{2}-\d{2}\ \d+:\d+:\d+):
(?:(?!^\d{4})[\s\S])+?
\QTHIS IS MATCHED STRING\E

请参见a demo on regex101.com