输出字符串被截断的行号时,Perl截断为Off-by-2

时间:2018-09-27 16:44:52

标签: perl io truncate truncation

无论何时发生截断,我都将从文本文件输出行号。我成功地获得了大多数截断行的输出。

但是,截断的行输出为2偏移。这是我的代码中发生的事情:

Rain是一个字符串,位于输入文本文件的第1行(请参见下文)。应用RegExp s/.{4}\K.*//s截断为4,Rain输出被截断,即使它没有被截断(Rain为4个字符也不需要将其缩短)。另外,它发生在5 s/.{5}\K.*//s

正确地,代码在被截断3个或更少时会输出截断的行。

使用s/.{4}\K.*//ss/.{5}\K.*//s时如何显示没有截断?换句话说,当我运行代码以截断4或5时,Rain不会显示行号的截断输出。

我的文本文件-weather.txt:

Rain
Snow

这是我的代码:

#!/usr/bin/perl
use strict;
use warnings;

my $input = 'weather.txt';

open my $fhIn, '<', $input or die qq(Unable to open "$input" for input: $!);

my @lines;

while( <$fhIn>) {
    chomp(@lines);
    push @lines, $. if s/.{5}\K.*//s;
}

my $max = @lines;
my $none = '-';

my $fmt = "%-20s\n";

print sprintf($fmt, "Column 1");

foreach my $i (0..$max-1) {
    print sprintf($fmt, ($lines[$i] or $none), ($lines[$i] or $none));
}

1 个答案:

答案 0 :(得分:3)

您的文本文件很可能在每行末尾包含回车符和换行符。 chomp调用只会删除换行符,在行中仅剩5个字符。

一种好的方法是print周围带有一些定界符以检查您的输入:

print "<<$_>>\n";

或者,您可以使用Data::Dumper来检查数据:

use Data::Dumper;
$Data::Dumper::Useqq = 1;
print Dumper $_;

我个人非常想删除输入行末尾的所有空格, 因为很少有人想要保留它:

while( <$fhIn> ) {
    s/\s+$//;
    push @lines, $. if s/.{5}\K.*//s;
};
相关问题