我有一个代码,它会为以&#34开头的所有行grep一个文件; BEGIN _"
将BEGIN_之后的单词匹配推送到@matching_lines
my $pattern = "BEGIN_";
my @matching_lines;
open(DATA, "<file.txt") or die "Couldn't open file file.txt, $!";
while(<DATA>){
if (/$pattern/) {
print "$_";
push(@matching_lines, $_);
}
}
当前输出
BEGIN_perl
BEGIN_ENV
BEGIN_shell
BEGIN_null
BEGIN_null_jdk1.7.0_11
BEGIN_ENV
BEGIN_WORKSPACE
BEGIN_SYNCHK_ASSET
BEGIN_SYNCHK_ASSET_ARGS
BEGIN_null_jenkins
期望输出
perl的
外壳
jdk1.7.0_11
詹金斯
答案 0 :(得分:2)
此程序从数组$exclude
构建正则表达式交替模式@exclude
,然后在主正则表达式模式中以负前向预测使用它。这排除了以任何排除的字符串开头的任何行,并且只选择那些以BEGIN_
开头的行
use strict;
use warnings 'all';
my $pattern = 'BEGIN_';
my @exclude = qw/
BEGIN_null
BEGIN_ENV
BEGIN_WORKSPACE
BEGIN_WORKSPACE
BEGIN_SYNCHK_ASSET
BEGIN_SYNCHK_ASSET_ARGS
/;
my @matching_lines;
my $exclude = join '|', map "\\b$_\\b", @exclude;
open my $fh, '<', 'file.txt' or die qq{Couldn't open file "file.txt": $!};
while ( <$fh> ) {
if ( /^(?!$exclude)$pattern(?:null_)?([\w.]+)/ ) {
print "$1\n";
push @matching_lines, $1;
}
}
perl
shell
jdk1.7.0_11
jenkins
进一步思考,我更倾向于一种不会将所有负担都放在单一正则表达式上的解决方案
就像这个while
循环一样,它可以直接替代前一个程序中的while
首先检查每一行是否以$pattern
开头,同时捕获字母数字,下划线或点的任何尾随字符。 next
中断循环并跳转到下一行输入
然后它测试该行是否以任何排除的字符串开头,再次使用next
忽略此类情况
剩余的任何内容都是感兴趣的行,并且要存储和打印
while ( <$fh> ) {
next unless /^$pattern(?:null_)?([\w.]+)/;
my $suffix = $1;
next if /^(?:$exclude)(?![\w.])/;
print "$suffix\n";
push @matching_lines, $suffix;
}
perl
shell
jdk1.7.0_11
jenkins