繁体   English   中英

正则表达式/ Perl以匹配包含字符串的文本块

[英]Regex/Perl to match blocks of text that contain a string

所以我有一个日志文件,看起来像这样:

EVENT-header
apple
orange
peach
blueberry

EVENT-header
bike
car
blueberry

EVENT-header
reddit
hacker news
stack overflow
slashdot?
voat

我想做的是提取包含单词“ peach”的文本块(从EVENT标头到下一个EVENT标头之前的两个换行符)。

我认为这是正则表达式可以解决的问题,但是我在制作能够做到这一点的正则表达式时遇到了麻烦。 到目前为止,这是我提出的内容:

's/EVENT-header((?!\n\n).)+peach((?!\n\n).)+\n\n/&/p'

我不是这个专家。 是否有使用regex / perl的简单方法?

您可以使用段落模式轻松完成此操作,该模式使perl读取由空白行分隔的文本块

perl -00 -ne'print if /peach/' logfile.log

如果您喜欢完整的程序文件,则它看起来像这样

use strict;
use warnings;

open my $fh, '<', 'logfile.log' or die $!;

{
    local $/ = '';

    while ( <$fh> ) {
        print if /peach/;
    }
}
EVENT-header\n[\s\S]*?(?=(?:\n\nEVENT-header|$))

您可以使用它。请参阅演示。

https://regex101.com/r/hR7tH4/3

有多种方法可以做到这一点,多行正则表达式匹配是一个很好的选择。 如果数据文件看起来像常规文件一样,特别是每个“记录”都由标记“ EVENT-header”隔开,那么您还可以使用将$ /(aka $ RS aka $ INPUT_RECORD_SEPARATOR)设置为标记的技巧然后将文件插入到数组中。 您将为文件中的每个记录获取一个数组条目,然后遍历数组,选择与“桃子”匹配的元素并打印出整个包含的记录就很简单了。

例如:

#!/usr/bin/perl -w
use strict;

$/='EVENT-header';
my (@entries, $entry);
my $infile = 'data.txt';

open(IN, "<$infile") or die "Aaargh: $^E\n";
@entries = <IN>;
chomp @entries;
close(IN);

foreach $entry (@entries) 
{
  if ($entry =~ m/peach/)
  {
    print "matching entry: $entry\n";
  }
}

Borodin已经为您的问题提供了最佳解决方案。 但是如果您不想使用一个衬板,这里是一个代码:

#!/usr/bin/perl
use warnings;
use strict;

local $/ = "";  #to enable paragraph mode

open my $fh, "<", "input.log" or die "Unable to open file: $!";

while (my $line = <$fh>)
{
    chomp $line;
    if ($line =~ m/peach/)
    {
        print $line, "\n";
    }   
}

输出:

EVENT-header
apple
orange
peach
blueberry

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM