解析时Perl“擦除”字符

时间:2016-04-28 13:51:53

标签: perl parsing data-scrubbing

我正在解析文件 - 我做的第一件事是连接前三个字段并将它们添加到每个记录中。然后我想清理任何冒号,单引号,双引号或反斜杠的数据。以下是我的做法,但有没有办法让我使用更有效的$ 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];

2 个答案:

答案 0 :(得分:2)

对我来说什么更干净:

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

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

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

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

答案 1 :(得分: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