从任何一种标量,我可以使用什么正则表达式来匹配它的前五行并丢弃其余的?
问问题
1596 次
8 回答
9
奇怪的请求,但这应该这样做:
#!/usr/bin/perl
use strict;
use warnings;
my $s = join '', map { "$_\n" } 1 .. 9;
my ($first) = $s =~ /^((?:.*\n){0,5})/;
my ($last) = $s =~ /((?:.*\n){0,5})$/;
print "first:\n${first}last:\n$last";
一个更常见的解决方案是这样的:
#!/usr/bn/perl
use strict;
use warnings;
#fake a file for the example
my $s = join '', map { "$_\n" } 1 .. 9;
open my $fh, "<", \$s
or die "could not open in memory file: $!";
my @first;
while (my $line = <$fh>) {
push @first, $line;
last if $. == 5;
}
#rewind the file just in case the file has fewer than 10 lines
seek $fh, 0, 0;
my @last;
while (my $line = <$fh>) {
push @last, $line;
#remove the earliest line if we have to many
shift @last if @last == 6;
}
print "first:\n", @first, "last:\n", @last;
于 2009-04-22T11:15:25.600 回答
6
你为什么不直接使用head
它?
于 2009-04-22T10:33:52.313 回答
3
你不需要正则表达式。只需在对标量的引用上打开一个文件句柄,然后对任何其他类型的文件句柄执行相同的操作:
my $scalar = ...;
open my($fh), "<", \ $scalar or die "Could not open filehandle: $!";
foreach ( 1 .. 5 )
{
push @lines, scalar <$fh>;
}
close $fh;
$scalar = join '', @lines;
于 2009-04-22T19:03:10.700 回答
2
my ($first_five) = $s =~ /\A((?:.*\n){5})/;
my ($last_five) = $s =~ /((?:.*\n){5})\z/;
于 2009-04-22T12:09:10.883 回答
2
正如布赖恩所说,你可以使用head
ortail
很容易地解决任何一个问题(前 5 行或后 5 行)。
但现在我想知道我是否正确理解了你的问题。当您说“对于任何类型的标量”时,您的意思是(无论出于何种原因)文件已经是标量吗?
如果不是,我认为最好的解决方案是根本没有正则表达式。使用$.
并正常或向后读取文件。要向后阅读,您可以尝试File::ReadBackwards
或File::Bidirectional
。
于 2009-04-22T12:16:24.970 回答
1
人们缺少一些关键标志:
/(?m)((?:^.*\n?){1,5})/
如果没有多行标志,它只会查看第一行。同样通过使选项成为\n
可选,我们可以取前五行,而不管第五行末尾的换行符。
于 2009-04-22T14:15:33.670 回答
1
为什么不只使用带限制的拆分,它就是为此目的而设计的:
my @lines = (split /\n/, $scalar, 6)[0..4];
如果您希望将其作为具有五行的单个标量返回,请将其连接起来:
my $scalar = join('\n', @lines) . "\n";
于 2009-04-23T02:54:03.813 回答
0
use strict;
my $line; #Store line currently being read
my $count=$ARGV[1]; # How many lines to read as passed from command line
my @last; #Array to store last count lines
my $index; #Index of the line being stored
#Open the file to read as supplied from command line
open (FILE,$ARGV[0]);
while ($line=<FILE>)
{
$index=$.%$count; # would help me in filter just $count records of the file
$last[$index]=$line; #store this value
}
close (FILE);
#Output the stored lines
for (my $i=$index+1;$i<$count;$i++)
{
print ("$last[$i]");
}
for (my $i=$0;$i<=$index;$i++)
{
print ("$last[$i]");
}
于 2010-03-14T12:15:07.100 回答