Perl 查询最短算法

  • 本文关键字:算法 查询 Perl perl
  • 更新时间 :
  • 英文 :


我有一个文本文件,如下所示:

AAA bbb_ccc 日ee_ff千兆克 呵�� AAA mm_nn_o P QQ RR ss_t AAA uu_lfpr LKL dde ldk_tr_lp

我想对任何以aaa开头的行进行 grep ,每次我找到此行匹配时,我都想将该行和所有后续行(空行除外(复制到新的文本文件中,直到下一个匹配。在上面的示例中,我要复制到的新文本文件应如下所示:

文件1

AAA bbb_ccc 日ee_ff千兆克 hh i j kk l

file2

AAA mm_nn_o P qq rr ss_t

file3

AAA uu_lfpr LKL dde ldk_tr_lp

我们可以使用任何简短的算法来实现这一点吗?我不想使用标志或开关来执行此操作并制作长代码。我想知道是否有任何函数或任何内置子例程可以用更短的代码来做到这一点。

这里有几个草图,直到显示一些代码,我可以根据需要详细说明。

要点:不需要标志。只需在每场比赛中打开一个新文件

my ($cnt, $fh_out);
while (<$fh_input>) { 
if (/^s*aaa/) {
++$cnt;
open $fh_out, '>', "file$cnt.txt" or do { warn $!, next };
}
print $fh $_;
}

如果打开文件句柄,则打开文件句柄会首先将其关闭,因此以前的写入是安全的,并且会打开新文件。

或者,如果您希望使用单行正则表达式来解析输入文件

my $content = do { local (@ARGV, $/) = $filename; <> };
my @blocks = $content =~ /(aaa (?: (?!aaa). )+ )/sxg; 
for my $i (0..$#blocks) { 
open my $fh, '>', 'file'.($i+1).'.txt'  or do { warn $!, next };
print $fh $blocks[$i];
}

我的最短:

my $n = 1; # File number
while (<>) {
open (STDOUT, '>', 'file' . $n++) if /^aaa/;
print;
}

或者使用 split

use strict;
use warnings;
use feature 'say';
my $data    = do { local $/; <> };
my @array   = split(/(?=(?:aaa))/,$data);
my $count   = 1;
for (@array) {
open STDOUT , '>' , 'file' . $count++;
print;
}

注意:open STDOUT , '>' , 'file' . $count++;借用了割礼——简单的方法

最新更新