字符串连接的意外结果

时间:2014-08-19 13:30:47

标签: perl

我编写了以下代码,用于从每行的文件名文件列表中读取并向其追加一些数据。

open my $info,'<',"abc.txt";
while(<$info>){

    chomp $_;
    my $filename = "temp/".$_.".xml";

    print"\n";
    print $filename;
    print "\n";

}

close $info;

abc.txt的内容

file1
file2
file3

现在我期待我的代码给我输出

temp/file1.xml
temp/file2.xml
temp/file3.xml

但我正在获得输出

.xml/file1
.xml/file2
.xml/file3

2 个答案:

答案 0 :(得分:7)

您的文件有Windows行结尾\r\nchomp移除\nNewline),但离开\rCarriage return)。将Data::DumperUseqq一起使用,您可以检查变量:

use Data::Dumper;
$Data::Dumper::Useqq = 1;
print Dumper($filename);

这应输出如下内容:

$VAR1 = "temp/file1\r.xml";

正常打印时,会输出temp/file,将光标移动到行首,并用temp覆盖.xml

要删除行结尾,请将chomp替换为:

s/\r\n$//;

@Borodin

指出
s/\s+\z//;

“具有为任何行终止符工作的优点,以及删除尾随空格,这通常是不需要的”

答案 1 :(得分:0)

如上所述,您的文件有窗口行结尾。

以下自包含示例演示了您正在使用的内容:

use strict;
use warnings;

open my $info, '<', \ "file1\r\nfile2\r\nfile3\r\n";
while(<$info>){
    chomp;
    my $filename = "temp/".$_.".xml";

    use Data::Dump;
    dd $filename;

    print $filename, "\n";
}

输出:

"temp/file1\r.xml"
.xml/file1
"temp/file2\r.xml"
.xml/file2
"temp/file3\r.xml"
.xml/file3

现在有两种方法可以解决这个问题

  1. $INPUT_RECORD_SEPARATOR调整为您的文件。

    local $/ = "\r\n";
    
    while(<$info>){
        chomp;
    

    chomp会自动处理$/

  2. 的值
  3. 使用正则表达式而不是chomp来删除行结尾

    perl 5.10起,有一个转义码\R代表通用换行符

    while(<$info>){
        s/\R//;
    

    或者,您可以删除所有尾随间距,以更加确定覆盖您的基础:

    while(<$info>){
        s/\s+\z//;