您好我想在文件中搜索与此类似的内容:
Start Cycle
report 1
report 2
report 3
report 4
End Cycle
....继续......
我想搜索“Start Cycle”,然后从中提取报告1并报告3 ..我的正则表达式看起来像这样
(Start Cycle .*\n)(.*\n)(.*\n)(.*\n)
上面的正则表达式选择Start Cycle和接下来的三行..但是我想从结果中省略thrid行。那可能吗?或者任何更简单的perl脚本都可以完成? 我期待的结果如下:
Start Cycle
report 1
report 3
答案 0 :(得分:5)
以下代码打印Start Cycle
和End Cycle
之间的奇数行:
foreach (<$filehandle>) {
if (/Start Cycle/ .. /End Cycle/) {
print if /report (\d+)/ and $1 % 2;
}
}
答案 1 :(得分:2)
您可以在开始和结束标记之间找到文本,然后按行分割上下文。这是一个例子:
my $text = <<TEXT;
Start Cycle
report 1
report 2
report 3
report 4
End Cycle
TEXT
## find text between all start/end pairs
while ($text =~ m/^Start Cycle$(.*?)^End Cycle$/msg) {
my $reports_text = $1;
## remove leading spaces
$reports_text =~ s/^\s+//;
## split text by newlines
my @report_parts = split(/\r?\n/m, $reports_text);
}
答案 2 :(得分:2)
也许这是一种疯狂的方式:改变Perl对输入记录的理解。
$/ = "End Cycle\n";
print( (/(.+\n)/g)[0,1,3] ) while <$file_handle>;
答案 3 :(得分:1)
正则表达式使用每对括号的内容填充1美元,2美元,3美元和4美元。
因此,如果你只看$ 1,$ 2和$ 4的内容就可以得到你想要的东西。
或者你也可以不用第三行的括号。
你的正则表达式应该类似于
/Start Cycle\n(.+)\n.+\n(.+)\n.+\nEnd Cycle/g
/ g将允许您重复评估正则表达式,并且每次都能获得下一个匹配。
答案 4 :(得分:1)
如果你想让所有周围的代码保持不变但是停止捕获第三件事,你可以简单地删除导致该行捕获的parens:
(Start Cycle .*\n)(.*\n).*\n(.*\n)
答案 5 :(得分:1)
我将OP的问题作为Perl练习,并提出以下代码。它只是为了学习目的而编写的。如果有什么看起来很可疑,请向我纠正。
while(<>) {
if(/Start Cycle/) {
push @block,$_;
push @block, scalar<> for 1..3;
print @block[0,1,3];
@block=();
}
}
另一个版本(编辑并感谢,@ FM):
local $/;
$_ = <>;
@block = (/(Start Cycle\n)(.+\n).+\n(.+\n)/g);
print @block;
答案 6 :(得分:0)
更新:我最初没有注意到这只是@FM's answer,只是稍微强一些,而且形式更长。
#!/usr/bin/perl
use strict; use warnings;
{
local $/ = "End Cycle\n";
while ( my $block = <DATA> ) {
last unless my ($heading) = $block =~ /^(Start Cycle\n)/g;
print $heading, ($block =~ /([^\n]+\n)/g)[1, 3];
}
}
__DATA__
Start Cycle
report 1
report 2
report 3
report 4
End Cycle
输出:
Start Cycle report 1 report 3
答案 7 :(得分:0)
while (<>) {
if (/Start Cycle/) {
print $_;
$_ = <>;
print $_;
$_ = <>; $_ = <>;
print $_;
}
}