如何使用正则表达式删除csv文件中字符串中特定字段的前导和尾随空格

时间:2017-12-21 05:33:34

标签: perl

我们在这里输入:

X,XXXXX,XXXXXX,  YYYYYY ,TTTTTTT,XXXXXXX,XXXXX  XXXX
Y,YYYYY,YYYYYY,YYY, XXXXXXX    ,TTTTTT,XX XXXX,XX

我尝试使用正则表达式:s/\s//g但是这个替换符将替换字符串中的所有空格ANYWHERE。

请建议正则表达式只修剪和跟踪整个字符串中的特定字段??

预期输出为:

X,XXXXX,XXXXXX,YYYYYY,TTTTTTT,XXXXXXX,XXXXX  XXXX
Y,YYYYY,YYYYYY,YYY,XXXXXXX,TTTTTT,XX XXXX,XX

删除该特定字段之前和之后的空格。它不会打扰已经有空间的其他领域。

2 个答案:

答案 0 :(得分:1)

注意这与字符串或多或少如图所示,字段内严格没有逗号

如果问题与常规CSV文件有关,请不要考虑正则表达式。使用模块解析文件并选择所需的字段。这是我想到的最多recent post(您不希望想要allow_whitespace用于您的目的)。还有更多,请搜索。

使用空格捕获所有字段,作为非逗号字符

my @m = $string =~ /([^,]+)/g;

然后清理你想要的东西并加入他们

$m[2] =~ s/^\s+|\s+$//g;
$string = join '', @m;

注意:单独删除空格s/^\s+//; s/\s+$//;

会更快

或者,对于在修剪字段中没有多个单词的字符串

perl -Mstrict -wE'
    $_ = q( xxx ,   yyy ,hey,zz ,  aaa); say;
    my $N = 2;
    my $c; 
    s/(\s*([^, ]+)\s*)/++$c==$N ? $2 : $1/eg; say
'

打印

 xxx ,   yyy ,hey,zz  ,  aaa
 xxx ,yyy,hey,zz  ,  aaa

或者,如果字符串在字段中可能有多个单词

perl -Mstrict -wE'
    $_ = q( xxx ,   yyy more ,hey,zz oo ,  aaa); say;
    my $N = 2;
    my $c; 
    s/(\s*( (?:[^,]+)?[^, ] )\s*)/++$c==2 ? $2 : $1/gex; say
'

这些适用于来自$N

的所有1..5

答案 1 :(得分:0)

所以我有两个可能的答案。一个人使用split,因为你的CSV文件是“基本的” - 没有引用的逗号/换行等,所以很长。

虽然它涵盖了大部分内容,所以我建议将它们作为一个很好的起点。

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


while ( <DATA> ) {    
   my @row = split /,/;
   s/^\s+// for @row;
   s/\s+$// for @row; 
   print join (",", @row),"\n";
}

__DATA__
X,XXXXX,XXXXXX,  YYYYYY ,TTTTTTT,XXXXXXX,XXXXX  XXXX
Y,YYYYY,YYYYYY,YYY, XXXXXXX    ,TTTTTT,XX XXXX,XX

如果它有点复杂的话,是时候突破Text::CSV

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

use Text::CSV; 

my $csv = Text::CSV -> new (); 

while ( my $row = $csv -> getline ( \*DATA ) )  {    
   s/^\s+// for @$row;
   s/\s+$// for @$row; 
   print join (",", @$row),"\n";
}


__DATA__
X,XXXXX,XXXXXX,  YYYYYY ,TTTTTTT,XXXXXXX,XXXXX  XXXX
Y,YYYYY,YYYYYY,YYY, XXXXXXX    ,TTTTTT,XX XXXX,XX

使用Text::CSV,您必须提供STDIN或将文件打开到CSV文件。使用split,您可以使用<>

然而,这两者都不是真正的“正则表达式”解决方案,因为IMO完全是错误的工具。