2

以下に示すファイルハンドルとしての文字列の解決策以外に、一度に1行ずつ複数行の文字列を処理するタスクの解決策を持っている人はいますか?

my $multiline_string = "line one\nline two\nline three\nline four";
my $filehandle;
open( $filehandle, '<', \$multiline_string )
    or croak("Can't open multi-line string as a filehandle: $!");
while ( defined (my $single_line = <$filehandle>) ) {
    # do some processing of $single_line here ...
}
close( $filehandle );

ファイルハンドルを使用したくない理由はかなり弱いです。Test :: Perl :: Criticは、ファイルハンドルのopenコマンドとcloseコマンドの間に10を超えるソース行があると泣き言を言います。$ single_lineの処理をかなり行っているので、実際には、オープン呼び出しとクローズ呼び出しの間に約40行のコードがあり、それを10に下げる方法がわかりません。

また、ビルドでPerl :: Criticalテストを無視したくありません。これは、コードで実際のディスクファイルを開くたびに合格したい、まともなテストだからです。

4

8 に答える 8

10

サブルーチンを作成し、ファイルの各行でそれを呼び出すことによって、Perl Criticを幸せにし、自分自身をさらに幸せにします。

use strict; use warnings;

sub do_something {
    my ($line) = @_;
    # do something with $line
}

open my $fh, '<', \$multiline_string
    or die "Cannot open scalar for reading: $!";

while(<$fh>) {
    chomp;
    do_something($_);
}

close $fh; 
于 2009-10-09T15:25:32.243 に答える
5

ええと、泣き言の目的は、たった1つのことを実行する小さなコードブロックを作成することではありませんか?各行に必要なことを実行するサブルーチンを作成します。

多くの人が提案していsplit /\n/ます。 split /^/ファイルハンドルの方法に似ています。

于 2009-10-09T16:00:27.817 に答える
3

どうですか:

my $multiline_string = "line one\nline two\nline three\nline four";
my @lines = split(/\n/,$multiline_string);
foreach my $line (@lines) {
    #do stuff with string
}
于 2009-10-09T15:24:55.080 に答える
3

私は何かが足りないかもしれませんが、あなたはできますか?

my @lines = split(/\n/,$multiline_string);
foreach my $single_line (@lines) {
  ...
}
于 2009-10-09T15:25:02.027 に答える
3

複数行の文字列をファイルハンドルにシューホーンできることを私が知るずっと前に、次のようなことがありましたsplit

foreach my $single_line (split /\n/, $multiline_string) {
    # process $single_line here
    # although note that it doesn't end in a newline anymore
}

リテラルおよび非ポータブルの使用に関する免責事項を\nここに挿入します。

于 2009-10-09T15:25:26.410 に答える
2

Perl :: Criticは素晴らしいですが、その任意の要件のいくつかに執着し始めると、それを節約するのではなく、時間を無駄にし始めます。ファイルハンドルをスコープから外すだけで、クローズについて心配する必要はありません。

 my $multiline_string = "line one\nline two\nline three\nline four";

 {
     open my( $fh ), '<', \$multiline_string )
         or croak("Can't open multi-line string as a filehandle: $!");
     while ( defined (my $single_line = <$fh>) ) {
         # do some processing of $single_line here ...
     }
 }

多くの人が正規表現や分割に手を伸ばしますが、それはずさんだと思います。新しいリストを作成して、プログラムでより多くのメモリを消費する必要はありません。

于 2009-10-09T19:08:00.297 に答える
0

正規表現を使用できます。

#!/usr/bin/perl

use strict;
use warnings;

my $s = "line one\nline two\nline three\nline four";

while ($s =~ m'^(.*)$'gm) {
    print "'$1'\n";
}

die "Exited loop too early\n" unless pos $s == length $s;

または、次を使用できますsplit

for my $line ( split m'\n', $multiline_string ){

  # ...

}
于 2009-10-09T15:34:36.590 に答える
-1

$/個人的には、複数行の文字列で行を区切るために使用するのが好きです。

my $multiline_string = "line one\nline two\nline three\nline four";
foreach (split($/, $mutliline_string)) {
  process_file($_);
}
sub process_file {
  my $filename = shift;
  my $filehandle;
  open( $filehandle, '<', $filename )
      or croak("Can't open multi-line string as a filehandle: $!");
  while ( defined (my $single_line = <$filehandle>) ) {
      process_line($single_line);
  }
  close( $filehandle );
}
sub process_line {
  my $line = shift;
  ...
}
于 2009-10-09T15:50:09.197 に答える