2017-12-21 15 views
-1

を使用してCSVファイル内の文字列内の特定のフィールドの先頭と末尾のスペースを削除するここでは、入力を行く:はどのように正規表現

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 

その特定のフィールドの前後のスペースを削除します。そしてそれはすでにそれにスペースがある他のフィールドを妨げることはありません。

+0

期待される出力は? –

+1

あなたの "_expected output_"はあなたの記述に完全に同意しません – zdim

答えて

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

+0

正規表現はcsvフィールドを分割するには不十分です – ysth

+1

@ysth Um ...もちろん - 私はOPスタイルの文字列を考慮しています。さもなければ正規表現は意味をなさない。 – zdim

+0

@ysth右、ありがとうございました...彼らは "CSVファイル"と言ってました... sigh – zdim

0

私は2つの可能な答えがあります。 1つは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を抜け出すための時間です:

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 

あなたはそれをSTDINを供給したり、CSVファイルにファイルを開く必要がありますどちらか。 splitでは<>を使用できます。

実際には、正規表現の解決策でもありません。それは、IMOがまったく間違った仕事のツールです。

+0

ありがとうSobrique ...その本当に役立ちます。しかし、もう一つの課題は、入力データが昏睡状態で終了したことです。例えば、 X、XXXXX、XXXXXX、YYYYYY、TTTTTTT、XXXXXXX、XXXXX XXXX ,,,,,,,,, Y、YYYYY、YYYYYY、YYY、XXXXXXX、TTTTTT 、XX XXXX、XX ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,。私は入力文字列の最後にスペースを追加しようとしました。あなたがこれを慰めるより良いアイデアを持っているならばお勧めします – CodeSeeker

関連する問題