Perl在substr()末尾添加CR

时间:2019-07-11 23:27:07

标签: perl substr

我正在执行此行以限制文本行的大小。 $Line=substr($_,0,12)。但是,如果发生截断,则返回的字符串结尾将缺少CR。没有截断,一切都OK。因此,当我打印行时,被截断的行没有CR,行继续并出现乱码。是否有任何内置功能可以自动执行此操作,还是需要额外的if-clause来解决此问题? 谢谢格特。

3 个答案:

答案 0 :(得分:2)

我认为您的意思是换行(0A),而不是回车(0D)。

解决方案是在截断行之前删除现有的换行符,然后再重新添加。

chomp;
$_ = substr($_, 0, 12);
say;

您当然也可以使用串联($_ .= "\n";)。

答案 1 :(得分:2)

一种方式

$line =~ s/(.{12}).*/$1/;

或者更好

$line =~ s/.{12}\K.*//;

其中\K删除所有先前的匹配项;请参阅“ 环顾四周断言in Extended Patterns in perlre。由于.与换行符不匹配,因此保留换行符。假定换行确实确实是“行”上的最后一件事。

但是,我发现剥离这些换行符并使用您的字符串更简单。然后在需要时添加换行符,大概是打印出来。


由于该行位于OP中的$_中,因此上述内容确实是

s/.{12}\K.*//;

或者,如果我们也想借此机会将(截断的)行分配给词法

my $line = s/.{12}\K.*//r;

其中/r修饰符使其返回更改后的字符串。感谢ysth和ikegami的评论。


该帖子最初声明“启动启动正则表达式引擎可能比substr + append 更昂贵”,这是对它的更新(逆向)。

我的基准测试表明,相比而言,正则表达式明显更快

$_ = substr($_, 0, 12) . "\n";

使用

s/.{12}\K.*//;

确切的基准测试结果在细节上有所不同,因为这是一项操作如此之快,开销会影响基准测试。但是我发现regex总是快很多(超过50%)。

答案 2 :(得分:1)

如果$ _长度大于12,则会发生带有代码截断的

$Line=substr($_,0,12)。如果$_值来自读取的行,则通常在结尾处有换行符\n 。当截断发生时,这当然会被删除。您可以使用以下方法手动添加它:

if (length $_ > 12) {$Line .= "\n";}

或者您可以在截断字符串之前执行chomp

chomp;
$Line  = substr($_,0,12);
$Line .= "\n";