我正在编写的Perl脚本需要解析一个文件,该文件具有诸如Makefile之类的延续行。即以空格开头的行是前一行的一部分。
我在下面编写了代码,但感觉不太干净或perl-ish(哎呀,它甚至不使用“redo”!)
边缘情况有很多:奇数处的EOF,单行文件,以空行(或非空行或连续行)开头或结尾的文件,空文件。我所有的测试用例(和代码)都在这里:http://whatexit.org/tal/flatten.tar
您可以编写更干净,性能更高的代码通过我的所有测试吗?
#!/usr/bin/perl -w
use strict;
sub process_file_with_continuations {
my $processref = shift @_;
my $nextline;
my $line = <ARGV>;
$line = '' unless defined $line;
chomp $line;
while (defined($nextline = <ARGV>)) {
chomp $nextline;
next if $nextline =~ /^\s*#/; # skip comments
$nextline =~ s/\s+$//g; # remove trailing whitespace
if (eof()) { # Handle EOF
$nextline =~ s/^\s+/ /;
if ($nextline =~ /^\s+/) { # indented line
&$processref($line . $nextline);
}
else {
&$processref($line);
&$processref($nextline) if $nextline ne '';
}
$line = '';
}
elsif ($nextline eq '') { # blank line
&$processref($line);
$line = '';
}
elsif ($nextline =~ /^\s+/) { # indented line
$nextline =~ s/^\s+/ /;
$line .= $nextline;
}
else { # non-indented line
&$processref($line) unless $line eq '';
$line = $nextline;
}
}
&$processref($line) unless $line eq '';
}
sub process_one_line {
my $line = shift @_;
print "$line\n";
}
process_file_with_continuations \&process_one_line;
最佳答案
如何将整个文件保存到内存中并使用正则表达式进行处理。更多的“完成”。这可以通过您的测试,并且更小,更整洁:
#!/usr/bin/perl
use strict;
use warnings;
$/ = undef; # we want no input record separator.
my $file = <>; # slurp whole file
$file =~ s/^\n//; # Remove newline at start of file
$file =~ s/\s+\n/\n/g; # Remove trailing whitespace.
$file =~ s/\n\s*#[^\n]+//g; # Remove comments.
$file =~ s/\n\s+/ /g; # Merge continuations
# Done
print $file;