-1

我正在解析一个文件 - 我做的第一件事是将前三个字段连接起来并将它们添加到每个记录中。然后我想擦洗任何冒号、单引号、双引号或反斜杠的数据。以下是我的做法,但有没有办法让我使用 $line 变量来做这件事会更有效?

# Read the lines one by one.
while($line = <$FH>) {

# split the fields, concatenate the first three fields,
# and add it to the beginning of each line in the file
    chomp($line);
    my @fields = split(/,/, $line);
    unshift @fields, join '_', @fields[0..2];

# Scrub data of characters that cause scripting problems down the line.
        $_ =~ s/:/ /g for @fields[0..39];
        $_ =~ s/\'/ /g for @fields[0..39];
        $_ =~ s/"/ /g for @fields[0..39];
        $_ =~ s/\\/ /g for @fields[0..39];
4

2 回答 2

2

什么对我来说更清洁:

while($line = <$FH>) {
    chomp($line);

    $line =~ s/[:\'"\\]/ /g;

    my @fields = split(/,/, $line);
    unshift @fields, join '_', @fields[0..2];
}

正如@HunterMcMillen 所说,如果这是一个标准的 CSV 文件,最好使用解析模块。以后会更容易。

于 2016-04-28T14:02:00.993 回答
1

我确信我以前见过一个非常相似的问题,但我的简单搜索不会找到它。突出的是在所有其他字段之前添加一个新字段,它是原始值的函数

你已经用 Perl 术语描述得最好了

unshift @fields, join '_', @fields[0..2];

所以剩下的唯一步骤是删除流氓字符——单引号和双引号、冒号和反斜杠

您的代码似乎工作正常。我会做的唯一改变是

  • 正确使用默认变量$_。我认为这是新手最讨厌 Perl 的地方,一旦他们了解了它就会爱上它

  • 使用tr///d而不是s///. 它可能会增加一点速度,但最重要的是,当您只想说出要删除的字符并需要更简单的内容时,您可以从正则表达式语法中解放出来

我认为这应该做你需要的

use strict;
use warnings 'all';

while ( <DATA> ) {

    chomp;
    my @fields = split /,/;

    unshift @fields, join '_', @fields[0..2];

    tr/:"'\\//d for @fields; # Delete colons, quotes, and backslash

    print join(',', @fields), "\n";
}

__DATA__
a:a,b"bb",c'ccc',ddd,e,f,g,h

输出

aa_bbb_cccc,aa,bbb,cccc,ddd,e,f,g,h
于 2016-04-28T16:50:48.497 回答