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

Perl truncation is Off-by-2 when outputting the line number for a string been truncated

每当 t运行cation 发生时,我都会从文本文件中输出行号。我成功地获得了大多数 t运行cated 行的输出。

然而,t运行cated 线路输出偏移了 2。这是我的代码中发生的事情:

Rain 是一个字符串,位于输入文本文件的第 1 行(见下文)。将 RegExp s/.{4}\K.*//s 应用到 t运行cate 到 4 并且 Rain 输出 t运行cated,即使它不是 t运行cated(Rain 是4个字符无需缩短)。此外,它发生在 5,s/.{5}\K.*//s

正确地,当 t运行cating 小于或等于 3 时,代码输出 t运行cated 行。

如何显示在使用 s/.{4}\K.*//ss/.{5}\K.*//s 时没有发生 t运行 阳离子?换句话说,当我 运行 我的代码在 4 或 5 上 t运行cate 时,Rain 不显示行号的 t运行cation 输出。

我的文本文件 - 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));
}

很可能,您的文本文件在每行的末尾包含一个回车符 return 和一个换行符。 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;
};