来自数组的串联字符串变量在Perl中给出了意外的引号

use*_*739 0 arrays string perl concatenation

我有一个CSV文件,我需要将每个值括在引号中,其中每个值都是一个字符串.连接时我得到意外的引用

$outline = "";
$line = "John,Smith,jsmith@bogusaddress.net,000-0000";
@parts = split (',',$line);
for $part (@parts) {
    $part = '"' . $part . '"';
    if ($outline eq "") {
        $outline = $part;                  # reconstruct line
    } else {
        $outline = $outline . "," . $part;
    }
}
$outline = $outline . "," . '"' . $parts[0] . " " . $parts[1] . '"';
print "$outline\n";
Run Code Online (Sandbox Code Playgroud)

我期望:

"John","Smith","jsmith.net","000-0000","John Smith"
Run Code Online (Sandbox Code Playgroud)

但我得到了:

"John","Smith","jsmith.net","000-0000",""John" "Smith""
Run Code Online (Sandbox Code Playgroud)

为什么我会得到额外的报价?

谢谢您的帮助.

TLP*_*TLP 6

已经提供了许多实用的解决方案,但是我想解决你的问题:为什么会这样?

你得到双引号的原因是你实际上是在改变元素@parts.在for循环内部,元素被别名化为循环参数,因此对它们的任何更改都是在"真实"值上进行的.考虑以下:

my @foos = 1 .. 3;
for my $foo (@foos) {
    $foo += 1;
}
print "@foos";  # prints 2 3 4
Run Code Online (Sandbox Code Playgroud)

因此,当您更改$part代码时,数组@parts也会更改,并且变为这样(Data::Dumper输出):

$VAR1 = [
          '"John"',
          '"Smith"',
          '"jsmith@bogusaddress.net"',
          '"000-0000"'
        ];
Run Code Online (Sandbox Code Playgroud)

从那时起,你不能把字符串放在一起,"John""Smith"不是先再删除引号.

我也准备了一个使用的解决方案Text::CSV,我看到ThisSuitIsBlackNot已经这样做了,所以你可以看看他的答案,找到一个实用的解决方案.

对于更轻量级的解决方案,您可以使用Text::ParseWords.这就像Text::CSV处理引用的分隔符一样.

use Text::ParseWords;

my $line = 'John,Smith,jsmith@bogusaddress.net,000-0000';
my @parts = quotewords(",", 0, $line);
push @parts, "@parts[0,1]";
print join ",", map qq("$_"), @parts;
Run Code Online (Sandbox Code Playgroud)