4

あらゆる種類のスカラーから、最初の 5 行を一致させ、残りを破棄するためにどの正規表現を使用できますか?

4

8 に答える 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

ブライアンが言うように、どちらの問題(最初の5行または最後の5行)にも使用できheadますtail

しかし今、私はあなたの質問を正しく理解しているのだろうかと思っています。「あらゆる種類のスカラーに対して」と言うとき、(何らかの理由で)ファイルがすでにスカラーになっていることを意味しますか?

そうでない場合、最善の解決策は正規表現をまったく使用しないことだと思います。を使用$.して、ファイルを通常どおりまたは逆方向に読み取ります。逆方向に読むには、File::ReadBackwardsまたはを試してくださいFile::Bidirectional

于 2009-04-22T12:16:24.970 に答える
2
my ($first_five) = $s =~ /\A((?:.*\n){5})/;
my ($last_five) = $s =~ /((?:.*\n){5})\z/;
于 2009-04-22T12:09:10.883 に答える
1

制限付きの分割を使用しないのはなぜですか。この目的のために設計されています。

my @lines = (split /\n/, $scalar, 6)[0..4];

それを5行の単一スカラーとして戻したい場合は、それを元に戻します。

my $scalar = join('\n', @lines) . "\n";
于 2009-04-23T02:54:03.813 に答える
1

人々はいくつかの重要なフラグを欠いています:

/(?m)((?:^.*\n?){1,5})/

複数行フラグがないと、最初の行のみが表示されます。また、 をオプションにすることで、5 行目の終わりの改行に関係なく、最初の 5\nを取ることができます。

于 2009-04-22T14:15:33.670 に答える
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 に答える