gpt4 book ai didi

perl - 保留输入中引用的 CSV 字段的引号

转载 作者:行者123 更新时间:2023-12-02 01:44:25 25 4
gpt4 key购买 nike

我有一个 CSV 文件,其中一些字段被引用,无论它们是否需要。我想要做的是加载此文件,修改一些值,并生成修改后的 CSV,其中引用的字段保持不变。

我目前正在使用 Perl 的 Text::CSV包试图解决这个问题,但遇到了一些障碍。以下是演示问题的小测试脚本:

use Text::CSV;

my $csv = Text::CSV->new ({'binary' => 1, 'allow_loose_quotes' => 1, 'keep_meta_info' => 1});
my $line = q^hello,"world"^;

print qq^input: $line\n^;

$csv->parse($line);
my @flds = $csv->fields();
$csv->combine(@flds);

print 'output: ', $csv->string(), "\n";

产生:

input:  hello,"world"
output: hello,world

根据 Text::CSV 的文档,一个 is_quoted()存在函数来测试输入中是否引用了某个字段,但如果我使用它向字段添加周围的引号,我会得到意想不到的结果:

my $csv = Text::CSV->new ({'binary' => 1, 'allow_loose_quotes' => 1, 'keep_meta_info' => 1});
my $line = q^hello,"world"^;

print qq^input: $line\n^;

$csv->parse($line);
my @flds = $csv->fields();

for my $idx (0..$#flds) {
if ($csv->is_quoted($idx)) {
$flds[$idx] = qq^"$flds[$idx]"^;
}
}

$csv->combine(@flds);

print 'output: ', $csv->string(), "\n";

制作:

input:  hello,"world"
output: hello,"""world"""

我相信我在 combine() 之前添加的引号被视为该字段的一部分,因此被第二个双引号转义为 combine() 正在处理中。

确保引用字段从输入到输出完好无损的最佳方法是什么?我不确定应用程序是否会接受 always_quote 编辑的字段...是否存在允许保持引号完整的 Text::CSV 对象属性的某种组合?或者也许我只剩下在 combine 后调整记录?

最佳答案

很遗憾,虽然 keep_meta_info 允许您访问元数据,但没有选项告诉 Text::CSV 重新应用 is_quoted 输出状态。

根据您的唱片的复杂程度,您可以自己重新组装。但是随后您将不得不应对字符串字段的更改,这些字段以前是安全地不加引号的,但在您处理之后现在需要引号。这将取决于您引入的更改类型,即您是否曾期望以前“安全”的字符串值会变得不安全。如果答案是“从不”(即 0.00000% 的可能性),那么您应该自己重新组装并记录您所做的事情。

后处理将要求您对字符串进行 CSV 解析以处理字符串中逗号和其他不安全字符的可能性,因此这可能不是一个选项。

或者,您可以深入研究 Text::CSV 的代码并实现所需的功能。 IE。允许用户在输出中强制引用特定字段。我试了一下,看起来所需机制的一部分可能已经到位,但不幸的是,我只能访问 XS 版本,它委托(delegate)给 native 代码,所以我现在无法深入研究。据我所知:

原始组合方法。请注意将 _FFLAGS 设置为 undef

sub combine
{
my $self = shift;
my $str = "";
$self->{_FIELDS} = \@_;
$self->{_FFLAGS} = undef;
$self->{_STATUS} = (@_ > 0) && $self->Combine (\$str, \@_, 0);
$self->{_STRING} = \$str;
$self->{_STATUS};
} # combine

我的尝试。我猜 Combine 的第二个参数可能是标志,但由于(小写)combine API 是基于接收数组而不是 arrayref,所以没有办法传入两个数组。我将其更改为期望有两个数组引用,并尝试将第二个数组传递给 Combine,但失败了 “无法在未祝福的引用上调用方法“print”” .

sub combine2
{
my $self = shift;
my $str = "";
my $f = shift;
my $g = shift;
$self->{_FIELDS} = $f;
$self->{_FFLAGS} = $g;
$self->{_STATUS} = (@$f > 0) && $self->Combine (\$str, $f, $g);
$self->{_STRING} = \$str;
$self->{_STATUS};
} # combine

关于perl - 保留输入中引用的 CSV 字段的引号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26569459/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com