【问题标题】:Perl truncation is Off-by-2 when outputting the line number for a string been truncated输出被截断的字符串的行号时,Perl 截断为 Off-by-2
【发布时间】:2018-09-27 16:44:52
【问题描述】:

每当发生截断时,我都会从文本文件中输出行号。成功地我得到了大多数截断行的输出。

但是,截断的行输出偏离 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));
}

【问题讨论】:

    标签: perl io truncate truncation


    【解决方案1】:

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

    【讨论】:

    • 成功了。非常感谢。还将检查数据转储器。
    • 您还可以在 Perl 5.10+ 上使用 s/\R\z// 来正确删除 CRLF 序列或单独的 CR 或 LF。注意 chomp() 仅删除 \n 因为在 Windows 上 :crlf 层默认应用于句柄,读取时将 CRLF 转换为 \n 。如果您希望在非 Windows 系统上出现这样的行尾,您可以自己应用此层。
    • 我们大多数人在理解换行、回车和其他空白材料时都非常放松。感谢@Grinnz 提供更多信息。
    猜你喜欢
    • 2012-02-10
    • 2013-06-07
    • 1970-01-01
    • 2011-06-05
    • 2020-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多