2

除了下面显示的 string-as-a-filehandle 解决方案之外,有没有人可以解决一次处理多行字符串的任务?

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 );

我不想使用文件句柄的理由很弱。当我在任何文件句柄上的打开命令和关闭命令之间有超过 10 条源代码行时,Test::Perl::Critic 会发牢骚。我正在对 $single_line 进行相当多的处理,所以在我的公开通话和关闭通话之间实际上有大约 40 行代码,我看不出有任何方法可以将其减少到 10 行。

而且我真的不想忽略构建中的 Perl::Critic 测试,因为这实际上是一个体面的测试,每当我在代码中打开一个实际的磁盘文件时,我都想通过它。

4

8 回答 8

10

通过创建一个子例程并在文件的每一行调用它,让 Perl 评论家开心,让自己更开心。

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

嗯,抱怨的目的不就是让你拥有只做一件事的更小的代码块吗?制作一个子程序来执行每行所需的操作。

很多人都建议过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 回答