perl regex CSV文件和列标题操作

时间:2014-12-15 20:33:05

标签: regex perl

首先,我问了一个类似的问题并得到了答案,但我没有想到我的价值观,只考虑了专栏。所以......

我有一个包含标题和值的多行文件。 因为这些值将被插入到数据库中,所以我想使用标题来表示列名。所以示例数据如下。

Sales-Date,2014-11-01
Item,Truck
Quantity,5,5
Sale Price,6,6
Discount,1,0
Cost of Item,3,3
Profit (loss),2,3

我已经运行了正则表达式来删除括号,并从列标题中删除

我需要一个正在查看该行的正则表达式,如果标题只是一个单词,则返回说出前4个字母,如果是多个单词,则返回每个单词的第一个字母。在所有情况下都需要返回逗号值。返回的所有内容都是大写的。所以期望的数据看起来像:

SD,2014-11-01
ITEM,Truck
SP,6,6
DISC,1,0
COI,3,3
PL,2,3

如果我不关心标题以外的字段,下面是正则表达式代码。对不起,我得到了所有,正如我所说,我修改它的尝试失败了。

#!/usr/bin/perl
use warnings;

my @arr = map {
 local $_ = uc;
 s/\s+\z//;
 /\s/ ? join("", /\b(\w)/g) : /(\w{1,4})/;
}
<DATA>;

print $_, "\n" for @arr;

__DATA__
Sales Date,4,5,6
Item,4,5,6
Sale Price,4,5,6
Discount,4,5,6
Cost of Item,4,5,6
Profit loss,4,5,6

如果 DATA 仅包含标题,并且没有逗号或其他值,则输出为:

SD
ITEM
SP
DISC
COI
PL

2 个答案:

答案 0 :(得分:1)

与往常一样,我建议使用Text::CSV来实际解析CSV文件,而不是滚动自己的解决方案。

无论哪种方式,以下附加逻辑可以帮助您根据您描述的规则重新格式化第一个字段:

#!/usr/bin/env perl
use strict;
use warnings;

while (<DATA>) {
    s{^([^,]*)}{
        my @words = $1 =~ /(\w+)/g;
        uc join '', map { substr $_, 0, @words > 1 ? 1 : 4 } @words;
    }e;
    print;
}

__DATA__
Sales-Date,2014-11-01
Item,Truck
Quantity,5,5
Sale Price,6,6
Discount,1,0
Cost of Item,3,3
Profit (loss),2,3

输出:

SD,2014-11-01
ITEM,Truck
QUAN,5,5
SP,6,6
DISC,1,0
COI,3,3
PL,2,3

答案 1 :(得分:1)

  

我需要一个正在查看该行的正则表达式,如果标题只是一个单词,则返回说出前4个字母,如果它的多个单词,则返回每个单词的第一个字母。在所有情况下都需要返回逗号值。返回的所有内容都是大写的。

这样的正则表达式,/ x模式与否,使得人们将Perl称为只写语言。

为什么不谨慎使用split(),substr()和join()?我的无聊,可读的解决方案如下所示,但我的代码的意图从我的代码的实现中非常清楚,它几乎不需要评论。

use strict;
use warnings;
while ( my $line = <$fh> ) {
  my ($identifier, @rest) = split(/,/, $line);   
  my @identifier_words = split(/ /, $identifier);
  my $new_identifier = '';
  if (@identifier_words == 1) {
    $abbreviated_identifier = substr($identifier_words[0], 0, 4);
  }
  else {
    foreach my $id_word (@identifier_words) {
      $abbreviated_identfier .= substr($id_word, 0, 1);
    }
  }
  $new_identifier = uc($new_identifier);
  my $new_line = join(',', $abbreviated_identifier, @rest);
  print $new_line;
}

__DATA__
Sales Date,4,5,6
Item,4,5,6
Sale Price,4,5,6
Discount,4,5,6
Cost of Item,4,5,6
Profit loss,4,5,6