我正在执行此行以限制文本行的大小。
$Line=substr($_,0,12)
。但是,如果发生截断,则返回的字符串结尾将缺少CR。没有截断,一切都OK。因此,当我打印行时,被截断的行没有CR,行继续并出现乱码。是否有任何内置功能可以自动执行此操作,还是需要额外的if-clause来解决此问题?
谢谢格特。
答案 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)
$Line=substr($_,0,12)
。如果$_
值来自读取的行,则通常在结尾处有换行符\n
。当截断发生时,这当然会被删除。您可以使用以下方法手动添加它:
if (length $_ > 12) {$Line .= "\n";}
或者您可以在截断字符串之前执行chomp
chomp;
$Line = substr($_,0,12);
$Line .= "\n";